-
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
Refetch should not trigger a field merge #7491
Comments
Any update on this? |
Also encountering this issue. I am using the new type policies and |
Btw for anyone hitting this issue I found the following acceptable workaround: use Perhaps the maintainers want to argue that this is in fact the correct solution..? It does however call into question what the legitimate use cases for |
For those of us using TypeScript and query variable types generated from |
My workaround is to use No extra parameter is needed😋 |
I have the same issue when useQuery is called multiple times and there is a merge policy, like when I display a page that has already been displayed previously in a React Native app. Still looking for a clean way to solve this |
Now that I’ve looked under the hood I can tell you why. When you use apollo-client/src/core/ObservableQuery.ts Lines 316 to 325 in 4fd6824
However... When you call apollo-client/src/core/QueryInfo.ts Lines 327 to 364 in 4fd6824
Here's the problem- |
@jtoce Thanks for digging into that! I think this should be fixable, given your analysis. |
Here's my current thinking on the original issue, as reported by @vigie and echoed by @JeffJankowski: If you define a However, I believe we can preserve this guarantee (that My current plan is to add an Of course, since you don't manually call I welcome your thoughts/questions about this idea. It is straightforward to implement, but needs more unit tests. I'll kick off a PR tomorrow, with the goal of releasing it in Apollo Client 3.4 (and in the next beta release, more immediately). The issue @jtoce identified in #7491 (comment) may well be a contributing factor (preventing writes in some cases, thereby not triggering any |
This is how I would ideally like to fix #7491, but I'm worried it could be a breaking change for any application code that relies on refetch results getting merged with existing data, rather than replacing it (which is what refetch was originally meant to do, since AC2). I will follow this commit with one that makes this the overwrite behavior opt-in (and thus backwards compatible).
The difference is that refresh overwrites existing fields by not passing existing data to field merge functions, whereas refetch passes existing data to merge functions, thereby combining it with the refetch result. If we continue down this path, we can say "the solution to #7491 is to switch from using refetch to using refresh," but that involves conscious effort by the developer, and would mean maintaining two very similar methods of the ObservableQuery class (refetch and refresh).
@vigie @JeffJankowski PR in progress—sorry for the wait! #7810 |
This is how I would ideally like to fix #7491, but I'm worried it could be a breaking change for any application code that relies on refetch results getting merged with existing data, rather than replacing it (which is what refetch was originally meant to do, since AC2). I will follow this commit with one that makes this the overwrite behavior opt-in (and thus backwards compatible).
The difference is that refresh overwrites existing fields by not passing existing data to field merge functions, whereas refetch passes existing data to merge functions, thereby combining it with the refetch result. If we continue down this path, we can say "the solution to #7491 is to switch from using refetch to using refresh," but that involves conscious effort by the developer, and would mean maintaining two very similar methods of the ObservableQuery class (refetch and refresh).
This reverts commit d87333b and introduces a new option for WatchQueryOptions called refetchPolicy. Because of the backwards compatibility concerns raised in #7810, the default setting for refetchPolicy needs to be "merge", though we hope developers will switch to refechPolicy:"overwrite" using the explicit option once Apollo Client v3.4 is released, to achieve the behavior I described in my comment #7491 (comment). We try to avoid introducing ad hoc new options, especially when we think one of the behaviors is preferable (overwriting, that is). However, since not all call sites of observableQuery.refetch are under the developer's control (for example, see refetchQueries after a mutation), it seemed important to have a way to _alter_ the behavior of refetch, rather than an alternative method (refresh). If one of these behaviors (hopefully "overwrite") becomes a clear favorite after Apollo Client v3.4 is released, we may either swap the default or remove the refetchPolicy option altogether in Apollo Client 4.
This reverts commit d87333b and introduces a new option for WatchQueryOptions called refetchPolicy. Because of the backwards compatibility concerns raised in #7810, the default setting for refetchPolicy needs to be "merge", though we hope developers will switch to refetchPolicy: "overwrite" using the explicit option once Apollo Client v3.4 is released, to achieve the behavior I described in my comment #7491 (comment). We try to avoid introducing ad hoc new options, especially when we think one of the behaviors is preferable (overwriting, in this case). However, since not all observableQuery.refetch call sites are under the developer's control (for example, see refetchQueries after a mutation), it seemed important to have a way to _alter_ the behavior of refetch, rather than a new alternative method (refresh). If one of these behaviors ("merge" or "overwrite") becomes a clear favorite after Apollo Client v3.4 is released, we may either swap the default or remove the refetchPolicy option altogether in Apollo Client 4.
Solve issue #7491 by supporting watchQueryOptions.refetchWritePolicy.
Really need this to be fixed, as I can't both use |
Intended outcome:
From the docs for refetch:
It seems wrong to me that when the new results come back it triggers the field's merge function. As we are resetting the variables the previous value for the query should be considered invalid and thrown out implicitly.
If there is not agreement on the above proposition, at the very least I would like to have a way to know that I'm in a merge function as the result of a refetch, so I can throw out the previous result explicitly.
Actual outcome:
The field's merge function is triggered and new results are merged with the old, creating an erroneous cache entry that results from a combination of old variable values and new.
How to reproduce the issue:
This is default behavior, trigger a refetch on a query whose result has a custom field merge policy. The problem is most easily identified in the context of list type fields and pagination.
Versions
The text was updated successfully, but these errors were encountered: