Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo Client delete Item from cache

Hy I'm using the Apollo Client with React. I query the posts with many different variables. So I have one post in different "caches". Now I want to delete a post. So I need to delete this specific post from all "caches".

const client = new ApolloClient({
    link: errorLink.concat(authLink.concat(httpLink)),
    cache: new InMemoryCache()
});

Postquery:

export const POSTS = gql`
    query posts(
        $after: String
        $orderBy: PostOrderByInput
        $tags: JSONObject
        $search: String
        $orderByTime: Int
    ) {
        posts(
            after: $after
            orderBy: $orderBy
            tags: $tags
            search: $search
            orderByTime: $orderByTime
        ) {
            id
            title
            ...
        }
    }
`;

I tried it with the cache.modify(), which is undefined in my mutation([https://www.apollographql.com/docs/react/caching/cache-interaction/#cachemodify][1])

const [deletePost] = useMutation(DELETE_POST, {
        onError: (er) => {
            console.log(er);
        },
        update(cache, data) {
            console.log(cache.modify())//UNDEFINED!!!
            cache.modify({
                id: cache.identify(thread), //identify is UNDEFINED + what is thread
                fields: {
                    posts(existingPosts = []) {
                        return existingPosts.filter(
                            postRef => idToRemove !== readField('id', postRef)
                         );
                    }
                }
            })
        }
    });

I also used the useApolloClient() with the same result.

THX for any help.

like image 654
Tölz Avatar asked Jul 31 '20 13:07

Tölz


People also ask

How do I clean my Apollo cache?

In your case, you can use the apollo's method client. resetStore(); It will clear the previous cache and then load the active queries.

Does Apollo Client cache?

Overview. Apollo Client stores the results of your GraphQL queries in a local, normalized, in-memory cache. This enables Apollo Client to respond almost immediately to queries for already-cached data, without even sending a network request. The Apollo Client cache is highly configurable.

Is Apollo cache persistent?

By default, the contents of your cache are immediately restored asynchronously, and they're persisted on every write to the cache with a short configurable debounce interval.


Video Answer


3 Answers

Instead of using cache.modify you can use cache.evict, which makes the code much shorter:

deletePost({
    variables: { id },
    update(cache) {
        const normalizedId = cache.identify({ id, __typename: 'Post' });
        cache.evict({ id: normalizedId });
        cache.gc();
    }
});
like image 115
Merlin04 Avatar answered Oct 17 '22 22:10

Merlin04


this option worked for me

const GET_TASKS = gql`
  query tasks($listID: String!) {
    tasks(listID: $listID) {
      _id
      title
      sort
    }
  }
`;

const REMOVE_TASK = gql`
  mutation removeTask($_id: String) {
    removeTask(_id: $_id) {
      _id
    }
  }
`;

const Tasks = () => {
  const { loading, error, data } = useQuery(GET_TASKS, {
    variables: { listID: '1' },
  });
  сonst [removeTask] = useMutation(REMOVE_TASK);

  const handleRemoveItem = _id => {
    removeTask({
      variables: { _id },
      update(cache) {
        cache.modify({
          fields: {
            tasks(existingTaskRefs, { readField }) {
              return existingTaskRefs.filter(
                taskRef => _id !== readField('_id', taskRef),
              );
            },
          },
        });
      },
    });
  };

  return (...);
};
like image 35
user2005679 Avatar answered Oct 17 '22 20:10

user2005679


You can pass your updater to the useMutation or to the deletePost. It should be easier with deletePost since it probably knows what it tries to delete:

    deletePost({
        variables: { idToRemove },
        update(cache) {
            cache.modify({
                fields: {
                    posts(existingPosts = []) {
                        return existingPosts.filter(
                            postRef => idToRemove !== readField('id', postRef)
                        );
                    },
                },
            });
        },
    });

You should change variables to match your mutation. This should work since posts is at top level of your query. With deeper fields you'll need a way to get the id of the parent object. readQuery or a chain of readField from the top might help you with that.

like image 3
UjinT34 Avatar answered Oct 17 '22 20:10

UjinT34