Search code examples
reactjsgraphqlapolloreact-apollographql-tag

How update Apollo Cache with a lot of active queries


I have a lot of active queries stored in my Apollo Cache, for example:

items(isPublished: true, orderBy: "name", filterByName: "")
items(isPublished: true, orderBy: "name", filterByName: "home")
items(isPublished: false, orderBy: "name", filterByName: "home")
items(isPublished: true, orderBy: "age", filterByName: "home")
...

and, consequently, a lot of possible variables for the same query (GET_ITEMS), with more and more filters. When I want to add, move or remove an item, I update the Apollo Cache with the propery update of Mutation component, for example:

import gql from "graphql-tag";
import { Mutation } from "react-apollo";

const ADD_ITEM = gql`
  mutation AddItem(...
`;

...

<Mutation mutation={ADD_ITEM} variables={...} update={() => ...} />

But, if I want well updated all my cached queries ... how I accomplish this? Would I have to cache.readQuery and cache.writeQuery inside update function for each query? That would be madness for me.

I'm lost with this. Thanks in advance.


Solution

  • This is one of the unfortunate limitations of ApolloClient, but can be solved by utilizing apollo-link-watched-mutation. The Link allows you to relate mutations and queries by operation name, such that for any mutation with a specific operation name, all queries with a particular operation name can be updated. The biggest downside to this approach is that it moves the update logic outside of your component and into your client configuration, which may obfuscate things a bit.

    Example usage, given a mutation named AddItem and queries named Items:

    const cache = new InMemoryCache()
    const link = new WatchedMutationLink(cache, {
      AddItem: {
        Items: ({ mutation, query }) => {
          const addedItem = mutation.result.data.addItem
          const items = query.result.items
          const items.push(addedItem)
          return {
             ...query.result,
            items,
          }
        }
      }
    })
    

    Note that you can inspect both the query and the mutation passed to the function to determine what, if anything, needs to be changed. Your actual code may be different based on what your queries actually look like, this is an example. See the docs for additional details.