question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cache.writeQuery in update on OptimisticResponse

See original GitHub issue

On an optimisticResponse, the cache.writeQuery inside update, triggers the query only for the optimistic data. It doesn’t trigger the query ( and hence re-render) when the update function runs the second time with the fetched data.

I would like it to trigger the query every time the cache.writeQuery runs. Below is how the mutation, optimistic response and update functions look.

       await createPost({
        variables,
        optimisticResponse: {
          __typename: 'Mutation',
          createPost: {
            __typename: 'Post',
            id: Math.round(Math.random() * -1000000),
            person: {
              __typename: 'Person',
             id: personId
            }
          }
        },
        update: async (store, { data: { createPost } }) => {
          let data = await store.readQuery({
            query: MyQuery,
            variables: {
              id : myId,
            }
          });

          function updateId(id) {
            return function(data) {
              data.my.posts = data.my.posts.filter((p) => p.id !== id);
              return data;
            }
          }

          data.my.posts.push(createPost);

          if (isNaN(Number(createPost.id))) {
            data = removeOptId(data)
          } else {
            removeOptId = updatePostId(createPost.id)
          }

          await store.writeQuery({
            query: MyQuery,
            variables: { id: myId },
            data
          });
        }
     })

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

8reactions
dobesvcommented, May 14, 2019

On further investigation I have found that it is not safe to modify the return value of readQuery and write it back to the store. Doing this may affect some cached data and give unexpected results. You should always use a copy-on-write approach with the return value of readQuery.

The reason my trick with doing a shallow copy of the query worked is that using a different object there affected the cache key apollo was using, so it returned a new object. Using the same document for the query meant that calls to readQuery and the Query component were sharing exactly the same object.

When the mutate call returns, the Query component checks if anything changes - however, it sees no change because its object was already updated when we modified the readQuery result data, so it does not re-render.

In the past there have been some examples and possibly even documentation suggesting that it is safe to mutate the return value of readQuery inside a mutation’s update function. However, I see some of those examples were adjusted to create a new object, and I can’t find any mention of this in the documentation (any more?).

In conclusion: to avoid weird caching problems, do not modify data returned from readQuery directly - any changes you make should be made to new objects of your own creation.

3reactions
dobesvcommented, May 14, 2019

I am having a similar issue, although without using optimistic response at all. writeQuery is not triggering an update of affected components. The workaround, weirdly, is to use a shallow clone of the query in readQuery, e.g.

let data = await store.readQuery({
            query: {...MyQuery},
            variables: {
              id : myId,
            }
          });

might fix your issue, if it’s the same weird one I’m investigating.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mutations in Apollo Client - Apollo GraphQL Docs
You can use this value to update the cache with cache.writeQuery , cache.writeFragment , or cache.modify . If your mutation specifies an optimistic...
Read more >
Mutation and update cache - typescript-react-apollo - Hasura
Finally we are writing the updated todo list to the cache using cache.writeQuery . Mapping Types. Now that the update mutation is completed,...
Read more >
Optimistic response not working when adding items to list
readQuery<GetAllListsQuery>({ query: GetAllListsDocument, })?.lists as TList[]) ?? []; if (data) { cache.writeQuery({ query: GetAllListsDocument ...
Read more >
Optimistic UIs with React, Apollo Client and TypeScript (Part II)
writeQuery and cache.modify , to update cached state. ... provide an optimisticResponse option to the addMessages options argument, ...
Read more >
How I met Apollo Cache - Medium
TL;DR. Do not use writeQuery , use writeData with optimisticResponse instead. ... refetchQueries is the simplest way of updating the cache.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found