Custom hook to Invalidate caches

I had this issue where I wanted to invalidate multiple queries (used in other components) after a mutation.
I first tried using the RefetchQueries and passed in my documents. But this did not trigger any of those queries to be refetched and the data remained invalid until refresh. Also I would have preferred the data to be refetched only when it was being requested again.
I then went through the docs a bit more and noticed:

You can only refetch active queries. Active queries are those used by components on the current page. If the data you want to update is not fetched by a component on the current page, it's best to update your cache directly.

So that got me thinking I needed to invalidate those caches ( I do not want to manually update the caches myself since I think this is a bit overkill for the application I am building ) After some looking around I found the cache.modify and DeleteModifier.
I now build a custom hook that I can pass in documents and they will get invalidated (so a refetch will trigger if the data is requested).

I posted my hook here:

So now in my mutations onCompleted callback I use

await deleteApolloCacheForDocuments([
  firstDocument,
  secondDocument,
]);

I was wondering why something like this is not included in ApolloClient and if there are better approaches to what I am trying to achieve here? Any remarks are welcome.

Updated gist to use cache.evict instead

Hey @peejee :wave:

Interesting approach! I’m curious, is this working for you? I was unable to get your gist working in the way you’d anticipate. In my testing, the cache was unmodified since calling cache.evict() with the query name rather than its fields resulted in a no-op. Instead, I was able to achieve the desired result by calling cache.evict on the root fields selected by those queries.

Apollo Client is a normalized cache, not a document based cache, so the query documents/names aren’t stored in the cache itself, hence why this wasn’t working for me.

I was wondering why something like this is not included in ApolloClient and if there are better approaches to what I am trying to achieve here? Any remarks are welcome.

I would refer again to the fact that Apollo Client uses a normalized cache, which provides a whole different way of thinking. Its easy for queries to have overlapping data which write to the same fields in the cache. Because of this, its difficult to us to prescribe an out-of-the-box behavior here because we want to give you the flexibility and tools to update the cache however you see fit in your app. Prescribing too aggressive of a cache eviction strategy by default might not fit in all situations, or worse, might remove too much cache data that you’d otherwise need to consume as part of another query or area of your UI, so we’d prefer to err on the side of doing little while giving you the tools to make the updates that fit your application.

Refetching queries is a pretty typical use case though for reloading data after a mutation (and generally the simplest), so having some kind of API has made sense here. In that way, your original issue with only active queries being fetched is a pretty common question/complaint we have with the way the refetchQueries API is currently designed. This is something in fact that we want to revisit in a future major to be a bit more intuitive. In fact, I just opened Revisit `refetchQueries` API · Issue #419 · apollographql/apollo-feature-requests · GitHub today as a way to track this. Hope this provides a bit more insight!