-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setVariables doesn't notify subscribers when cache hit #2712
Comments
I can confirm this behavior, we ran into this too. And it seems to be a bug. |
The same for |
+1 Here is test implementation example where we request dataOne, then dataTwo and again dataOne. In this case, a diff --git a/packages/apollo-client/src/core/__tests__/ObservableQuery.ts b/packages/apollo-client/src/core/__tests__/ObservableQuery.ts
index fca78f3d..7e42b736 100644
--- a/packages/apollo-client/src/core/__tests__/ObservableQuery.ts
+++ b/packages/apollo-client/src/core/__tests__/ObservableQuery.ts
@@ -679,6 +679,10 @@ describe('ObservableQuery', () => {
request: { query, variables: differentVariables },
result: { data: dataTwo },
},
+ {
+ request: { query, variables: variables },
+ result: { data: dataOne },
+ },
);
subscribeAndCount(done, observable, (handleCount, result) => {
@@ -691,6 +695,12 @@ describe('ObservableQuery', () => {
} else if (handleCount === 3) {
expect(result.loading).toBe(false);
expect(result.data).toEqual(dataTwo);
+ } else if (handleCount === 4) {
+ expect(result.loading).toBe(false);
+ expect(result.data).toEqual(dataTwo);
+ } else if (handleCount === 5) {
+ @expect(result.loading).toBe(true);
+ expect(result.data).toEqual(dataOne);
done();
}
}); |
Hi all - sorry for the delay in responding to this. TL;DR
BackgroundIn a nutshell,
It does this by watching for changes made in the Apollo Client store. The example listed in #2712 (comment) is using What has definitely added to the confusion here, is the fact that
So long story longer, |
This is a very surprising revelation as I was instinctively expecting to watch result changes, not store changes. And the docs in
Can you guarantee that if we use So far, I would suggest the following:
If you agree on the principle I can provide a PR for 1. |
About the potential behavior changes... in what kind of use-cases would it be preferable to watch the store, instead of watching the result for a public API ? From the consumer point of view it seems that the difference between store and result is very thin if not non-existent. If there aren't any strong use-cases for a public API to watch the store, then I'd say the behavior should change to always watch the results instead. Making the store even more transparent for the consumer for most common use-cases. |
@hwillson Thx for feedback. I'm observing a behavior I can't say if it matches the design you explain. What does determine if the store has change ? If I refetch from the server an item that is identical to the one that is on the store, has the store changed ? Here is the context of my question : I have two actions with id 123 and 456. I use fetchPolicy On first fetch, I watch the query with id 123. const queryRef = this.apollo.watchQuery({
query: actionsQuery,
variables: {id: 123},
});
queryRef.subscribe(result => console.log(result)); This cause networkStatus outputs successively
With successive calls to Now I execute with second id A query is sent to the server and the console.log (valueChanges) outputs successively :
The queryRef.valueChanges has been updated, but on networkStatus 2 and 1 we received old data. Question : is the old data here by design ? What's the point of it here ? It can cause the controllers to do some stuff with out of sync data. At this point, the actions id:123 and id:456 are both on the store.
Whether we alternate or not id when calling multiple times setVariables(), the store don't really change imho. The actions are already there. And so on |
This clarifies `setVariables` as for internal use only because it has a severe caveat where a result coming from cache will not notify subscribers. That makes it a poor choice for most common use cases. Instead `refetch` should be used and is now documented as such. Also clarifies that `watchQuery` does not watch the result, but the cache store, meaning that if the store does not change, the subcribers will not be notified. In practice that means that a result coming from cache will never be seen by subscribers. This partially address apollographql#2712
@hwillson I created #3692 to address the documentation issue, please have a look and let me know where I should add the CHANGELOG related to that. @s-panferov, contrary to what you said, I can confirm that @sambaptista I agree that receiving old data does not qualify as a cache change. And it adds to the confusion. So when @hwillson said:
It is incomplete and it should instead read:
It honestly feels awkward to write that |
This clarifies `setVariables` as for internal use only because it has a severe caveat where a result coming from cache will not notify subscribers. That makes it a poor choice for most common use cases. Instead `refetch` should be used and is now documented as such. Also clarifies that `watchQuery` does not watch the result, but the cache store, meaning that if the store does not change, the subcribers will not be notified. In practice that means that a result coming from cache will never be seen by subscribers. This partially address apollographql#2712
To help provide a more clear separation between feature requests / discussions and bugs, and to help clean up the feature request / discussion backlog, Apollo Client feature requests / discussions are now being managed under the https://github.com/apollographql/apollo-feature-requests repository. Migrated to: apollographql/apollo-feature-requests#25 |
Migrated to apollographql/apollo-feature-requests#25, because the current situation is confusing at best or buggy at worst. |
Intended outcome:
Calling
setVariables()
on aObservableQuery
should notify subscribers of a data change. This works as expected if the query is not cached and results in a network request.Actual outcome:
If a query has been cached
setVariables()
does not notify its subscribers of the data change. From tracing the code it appears the correct data is pulled from the cache and set as the query result, however subscribers are never notified of the result like they are when a network query occurs.How to reproduce the issue:
app.module.ts
data.service.ts
view.component.ts
Versions
The text was updated successfully, but these errors were encountered: