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.modify refetches whole query when I try to update cache

See original GitHub issue

Hey everyone, I have a little issue when trying to update the cache using the new cache.modify feature.

My GraphQL query looks like this:

query Menus {
    viewer {
      id
      menuConnection {
        edges {
          node {
            id
            menuId
            label
            menuCategoryConnection {
              edges {
                node {
                  id
                  category {
                    id
                    label
                    subcategoryConnection {
                      edges {
                        node {
                          id
                          label
                          subcategoryItemConnection {
                            edges {
                              node {
                                id
                                item {
                                  id
                                  label
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }

When I add a new item to the subcategoryItemConnection and try to update cache after mutation, the cache.modify refetches the entire query as soon as I access a field of a store element, here is the code:

const [moveItem] = useMutation(MOVE_ITEM, {
    update: (cache, { data: { moveItem } }) => {
      cache.modify({
        id: cache.identify(moveItem.subcategory),
        fields: {
          subcategoryItemConnection(){
            /// ...cache update logic
          }
        },
      });
    },
  }); 
    }
  }

So as soon as I access the subcategoryItemConnection field the query gets refetched, any logic that I write inside the modifier function gets ignored. The way I understand it, the modifier function shouldn’t refetch the query it should do the opposite, allow me to update the cache without refetching all data from the backend. Can someone please tell me what the issue is or if I am understanding something wrong?

Thanks

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:15
  • Comments:23 (2 by maintainers)

github_iconTop GitHub Comments

16reactions
aquelehugocommented, Dec 14, 2020

We had that issue today and the problem was that the result from the mutation didn’t have the same fields the query had.

Our query was like this:

query {
  comments {
    edges {
      id
      content
      totalReplies
    }
  }
}

Our mutation was like this:

mutation {
  addComment {
    id
    content
  }
}

So, when we called cache.modify and added a reference to the recently created comment, the fields didn’t match and the query was refetched.

cache.modify({
   fields: {
     comments(previous, { toReference }) {
       return {
         ...previous,
         edges: [toReference(newComment), ...previous.edges],
       };
     },
   },
});

So we updated our mutation to return totalReplies, which was missing in comparison to our query fields and the refetching stopped.

mutation {
  addComment {
    id
    content
    totalReplies
  }
}

Our queries and mutations actually have a more complex structure, but I stripped it down to make the example more readable.

9reactions
pontusabcommented, Oct 2, 2020

From docs: Like writeQuery and writeFragment, modify triggers a refresh of all active queries that depend on modified fields (unless you override this behavior).

try to add broadcast: false like this:

const [moveItem] = useMutation(MOVE_ITEM, {
    update: (cache, { data: { moveItem } }) => {
      cache.modify({
        id: cache.identify(moveItem.subcategory),
        broadcast: false,
        fields: {
          subcategoryItemConnection(){
            /// ...cache update logic
          }
        },
      });
    },
  }); 
    }
  }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Reading and writing data to the cache - Apollo GraphQL Docs
Access the fields of any cached object without composing an entire query to reach that object. Directly modifying cached fields, cache.modify, Manipulate cached...
Read more >
GraphQL Cache Updates Made Easy - Christian Lüdemann
There are a couple of different ways to update cache after an update in this state management system: Refetch query; Built-in normalization; Update...
Read more >
Reading and writing data to the cache - Client (React)
readQuery and readFragment; writeQuery and writeFragment; cache.modify (a ... to the Apollo Client cache (including all active queries) see this change and ...
Read more >
Advanced Topics on Caching – Angular
It will then refetch those queries with their current variables. ... Using update gives you full control over the cache, allowing you to ......
Read more >
Tips and Tricks for working with Apollo Cache - Medium
When you make any graphQL query, by default Apollo caches the ... so we can bypass refetching and write directly to 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