question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

fetchMore and fetchPolicy: cache-and-network does not work together

See original GitHub issue

Intended outcome: In case of fetchMore additional request should not be executed or should use last variables (passed to fetchMore)

Actual outcome: The request executes with wrong variables

How to reproduce the issue:

function MyComponent() {
  const q = useQuery(query, { variables: { offset: 0 }, fetchPolicy: 'cache-and-network' });
  ...
  <button id="button" onClick={() => q.fetchMore({ variables: { offset: 10 } })}>Click me</button>
}

That’s what is happening:

  1. <MyComponent /> is rendered => request to the server is executed with { offset: 0 }
  2. Button #button clicked => request to the server is executed with { offset: 10 } => request to the server is executed with { offset: 0 }

In other words the request, which fetches fresh data from the server uses variables passed to the hook, but to to fetchMore

Versions

  System:
    OS: Windows 10 10.0.19041
  Binaries:
    Node: 12.18.0
    Yarn: 1.22.4
    npm: 6.14.4
  Browsers:
    Chrome: 84.0.4147.125
  npmPackages:
    @apollo/client: ~3.1.2 => 3.1.3
    apollo: ~2.30.2 => 2.30.2

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:33
  • Comments:31 (5 by maintainers)

github_iconTop GitHub Comments

18reactions
khitrenovichcommented, Mar 31, 2021

See also #6327 and #6833, especially this comment.

Looks like the proper policy combination in 2021 for paging+cache is

    fetchPolicy: 'cache-and-network',
    nextFetchPolicy: 'cache-first',
9reactions
benjamncommented, Aug 18, 2021

After thinking more about this, I agree with @Akryum the extra network fetch after fetchMore is not a reasonable consequence of using network-only or cache-and-network fetch policies.

Yes, you may be able to work around the problem with nextFetchPolicy: "cache-first", but I no longer think using nextFetchPolicy should be necessary in this case. As long as the cache read triggered by fetchMore is complete (in the diff.complete sense), I think we should deliver that cache result immediately, and skip the network. In other words, reacting to a fetchMore request is not one of the situations where we want/need to reapply the original query’s fetchPolicy literally, so I think it should be safe to ignore the fetchPolicy here, and just deliver the result.

I’m still investigating the consequences of these changes, but I think/hope we can remove the this.reobserve() from the finally after fetchMore, and change the QueryInfo code as follows:

commit 5c378d1d07a33ab4de0c14d2f6d68d48297ef9ec
Author: Ben Newman <ben@apollographql.com>
Date:   Tue Aug 17 16:00:56 2021 -0400

    Avoid full reobservation in QueryInfo listener when diff.complete.

diff --git a/src/core/QueryInfo.ts b/src/core/QueryInfo.ts
index ea23f374a..7f5b6ce5d 100644
--- a/src/core/QueryInfo.ts
+++ b/src/core/QueryInfo.ts
@@ -235,7 +235,8 @@ export class QueryInfo {
         // full reobservation, since oq.reobserve might make a network
         // request, and we don't want to trigger network requests for
         // optimistic updates.
-        if (this.getDiff().fromOptimisticTransaction) {
+        const diff = this.getDiff();
+        if (diff.complete || diff.fromOptimisticTransaction) {
           oq["observe"]();
         } else {
           oq.reobserve();

The observe method of ObservableQuery delivers the current result only, whereas reobserve reapplies the fetchPolicy, potentially delivering multiple results.

I hope to have more answers soon. Thanks to @akryum for sharing your findings!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using fetchPolicy='cache-and-network' in useQuery in apollo ...
I am using the apollo-client for my graphql setup. I have a paginated call for which i use the fetchMore function returned by...
Read more >
Interacting with cached data - Apollo GraphQL Docs
Since these queries are cached by both the initial query and their parameters, a problem arises when later retrieving or updating paginated queries...
Read more >
Pagination - Client (React) - Apollo GraphQL Docs
In Apollo, the easiest way to do pagination is with a function called fetchMore , which is included in the result object returned...
Read more >
subscribeToMore and fetchMore for the same querry using ...
I've been learning Graphql and started building fullstack app using Apollo. But I ran into a problem, where I have a query for...
Read more >
Understanding Apollo Fetch Policies | by Galen Corey - Medium
This becomes especially noticeable when you are working with data ... If you do not set a fetch policy yourself, this is what...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found