Apollo client: how to prevent related query refetch after cache update

Hi there,

I have a very specific case where we query a list of objects with id with let’s say query A. The result is used application wide.

At some point we query an other list which can include the same data as the first query has but now with query B.

When the new list arrives as result of query B right after that query A got refetched.

So when this query A resolves and the results written to the cache query B got refetched.

And it goes infinite.

Does somebody know how can I prevent the refetch of query A after query B returns the same object?

I think it is because each query contains an object which will update the entity cache which will invalidate the previous query cache which will trigger a auto refetch for the other query.

We tried to avoid this behaviour by setting up typePolice with keyFields: false to prevent the normalisation of the entity. It does not normalise (no root level caching) but still does the refetch.

Any ideas are welcome.

Thanks for your help!

All right, this post is not really attractive, I can tell.

To solve our problem I am thinking to disable the caching for those objects which are within the result list.
Is there away to do this? I know I can disable cache for certain type by setting the keyFields to false but I want to cache them except if they arrive in specified queries.

Eg: there is a User object which is the logged in user, this user can search for user list and this list can contain the user object itself. For some reason when the list arrives it triggers the refetch of the query which fetches the currently logged in user. And this will trigger to refetch the list.
Can you follow me?

A simplified example:

type User {
 id: String!
 name: String!
 email: String!
}

type GetCurrentUserResponse {
  result: User!
}

type SearchUsersResponse {
  results: [User!] # if the list contains the same object as the result of the getCurrentUser the AC will refetch the `getCurrentUser` query
  total: Int!
}

type Query {
  getCurrentUser: GetCurrentUserResponse
  searchUsers(filter: SearchUsersFilterInput!): SearchUsersResponse
}

I don’t think I can give you the solution here but maybe I can point you in the right direction. As far as I’m concerned, normally the behaviour that you’re describing should not be happening, and you should not be required to set any keyFields. searchUsers and getCurrentUser should yield completely different cache objects that might be referencing the same user, but even so, the presence of the same user in both results should not cause any cache invalidation or refetches. The only reason for a cache-first query to automatically refetch its data is if part of that data can’t be found in the cache.

That said, I would try the following:

  • Check the contents of the cache right before the searchUsers query goes through and right after. Does anything happen to the getCurrentUser cache at all or does it stay the same?
  • Do the searchUsers and getCurrentUser queries request the exact same User fields or do they differ? In the latter case, do you have a User type policy with a merge function that replaces any existing objects with the incoming object rather than merging them? That’s a really far-fetched guess here, but it would perfectly explain the behaviour you’re observing.

Hi @mindnektar ,
Thanks for your time. They sounds very promising. We will try it out next week. Will come back to you with the result. :slight_smile: