Deleting Apollo Client cache for a given query and every set of variables

Jean-Baptiste Rudant picture Jean-Baptiste Rudant · Feb 3, 2018 · Viewed 7.1k times · Source

I have a filtered list of items based on a getAllItems query, which takes a filter and an order by option as arguments.

After creating a new item, I want to delete the cache for this query, no matter what variables were passed. I don't know how to do this.

I don't think updating the cache is an option. Methods mentionned in Apollo Client documentation (Updating the cache after a mutation, refetchQueries and update) all seem to need a given set of variables, but since the filter is a complex object (with some text information), I would need to update the cache for every given set of variables that were previously submitted. I don't know how to do this. Plus, only the server does know how this new item impact pagination and ordering.

I don't think fetch-policy (for instance setting it to cache-and-network) is what I'm looking for, because if accessing the network is what I want after having created a new item, when I'm just filtering the list (typing in a string to search), I want to stay with the default behavior (cache-only).

client.resetStore would reset the store for all type of queries (not only the getAllItems query), so I don't think it's what I'm looking for either.

I'm pretty sure I'm missing something here.

Answer

Martin Hunt picture Martin Hunt · Oct 25, 2018

There's no officially supported way of doing this in the current version of Apollo but there is a workaround.

In your update function, after creating an item, you can iterate through the cache and delete all nodes where the key starts with the typename you are trying to remove from the cache. e.g.

// Loop through all the data in our cache
// And delete any items where the key start with "Item"
// This empties the cache of all of our items and 
// forces a refetch of the data only when it is next requested.
Object.keys(cache.data.data).forEach(key => 
  key.match(/^Item/) && cache.data.delete(key)
)

This works for queries that exist a number of times in the cache with different variables, i.e. paginated queries.

I wrote an article on Medium that goes in to much more detail on how this works as well as an implementation example and alternative solution that is more complicated but works better in a small number of use cases. Since this article goes in to more detail on a concept I have already explained in this answer, I believe it is ok to share here: https://medium.com/@martinseanhunt/how-to-invalidate-cached-data-in-apollo-and-handle-updating-paginated-queries-379e4b9e4698