The application initializes:
watchQuery() with fetchPolicy "cache-and-network" and waits for a responsequery() and quickly receives the responseIntended outcome:
I would expect apollo client to process the response of query() and keep waiting for the first watchQuery result.
Actual outcome:
The plain query sends a notification that triggers a reobserve in the watchQuery, which makes a refetch.
Step by step
Plain query finishes, calls stopQuery()
https://github.com/apollographql/apollo-client/blob/bd778d17411863bcefbb3302befe8ae6c3276e44/src/core/QueryManager.ts#L494
Which makes a broadcast to all queries
https://github.com/apollographql/apollo-client/blob/bd778d17411863bcefbb3302befe8ae6c3276e44/src/core/QueryManager.ts#L653
watchQuery thinks it should be notified in shouldNotify
https://github.com/apollographql/apollo-client/blob/bd778d17411863bcefbb3302befe8ae6c3276e44/src/core/QueryInfo.ts#L209-L214
Previously, watchQuery created a listener and it's now called.
https://github.com/apollographql/apollo-client/blob/bd778d17411863bcefbb3302befe8ae6c3276e44/src/core/QueryInfo.ts#L183
reobserve() then makes watchQuery to refetch again
Versions
3.2.0
Is there any workaround for this issue? Maybe you could call refetch in an effect to emulate how cache-and-network normally behaves?
@joshjg I don't know if you refer to ObservableQuery.refetch or mutate(, { refetchQueries }), but both work in a similar way. In my opinion refetchQueries scales better.
cache-first in watchQuery + manual refetchQueries in mutations should suffice as a workaround. Note however that it involves quite a lot of work.
First, for every watchQuery you have to store the query and variables somewhere. Second, every time the variables of a watchQuery are updated, the stored refetchQuery must be updated. Finally you have to decide which refetchQueries should be passed to each mutation. If anyone modifies a query or a mutation, they should rethink again which refetchQueries to pass.
@javier-garcia-meteologica That's a good idea, but what about cases such as "reloading the page"?
Like, if you reload the page, the apollo cache is lost. Thus, each query now is useless if it only uses cache-first, because it requires a mutation for it to get data from the network/backend.
Unless, I dont understand very well the issue, for which I would like to apologize. :P Feel free to correct me if that's the case. :)
@exapsy cache-first should automatically make network requests if and only if it doesn't find suitable data in cache.
Ah yeah you're right. I'm sorry, it was a long night and totally I misread that!
Which makes it a great idea. Thank you!
@benjamn I noticed that #6891 actually mitigates this issue (at least in my case) - however, that commit was later reverted.
Here is a repro
The bug is introduced somewhere between these two versions: https://github.com/apollographql/apollo-client/compare/v3.1.0-pre.3...v3.1.0-pre.4
Of those commits only this one looks relevant: https://github.com/apollographql/apollo-client/commit/1cd1df9b6aa3c70eed6ddc378451c7f9cc79514a
Sure enough, adding nextFetchPolicy: 'cache-first' to my query solves the issue and seems like a reasonable workaround.
Most helpful comment
Here is a repro
The bug is introduced somewhere between these two versions: https://github.com/apollographql/apollo-client/compare/v3.1.0-pre.3...v3.1.0-pre.4
Of those commits only this one looks relevant: https://github.com/apollographql/apollo-client/commit/1cd1df9b6aa3c70eed6ddc378451c7f9cc79514a
Sure enough, adding
nextFetchPolicy: 'cache-first'to my query solves the issue and seems like a reasonable workaround.