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` causes redundant request with fetchPolicy `network-only` and `cache-and-network`

See original GitHub issue

Intended outcome: Calling fetchMore causes single network request when query fetchPolicy is network-only or cache-and-network.

Actual outcome: fetchMore causes two requests: one for fetching requested page and second is always refetching first page.

How to reproduce the issue:

  1. open repro https://codesandbox.io/s/nostalgic-sammet-wlhrq?file=/src/Todos.tsx
  2. open network inspector
  3. click “Load more”
  4. inspect requests inside wlhrq.csb.app frame, you will see two requests for every next page load

Versions

System:
  OS: macOS 11.1
Binaries:
  Node: 14.15.4 - /usr/local/bin/node
  Yarn: 1.12.3 - /usr/local/bin/yarn
  npm: 6.14.10 - /usr/local/bin/npm
Browsers:
  Chrome: 88.0.4324.150
  Safari: 14.0.2

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

9reactions
picosamcommented, Apr 8, 2021

@gbiryukov The client is doing exactly what you’ve asked it to do here!

Since fetchMore works by updating the cache, if you want to render those updates without making an additional network request, you need a fetchPolicy that’s allowed to read from the cache, rather than (just) network-only. If you stick with fetchPolicy: "network-only" after the first request, the client’s only option for responding to cache updates from fetchMore is to perform an additional network request. The cache-and-network policy allows reading from the cache, which is a step in the right direction, but it also makes an unconditional network request, so that’s not exactly what you want. Here’s a summary of the history of these behaviors, in case you’re curious: #6760 (comment)

Based on your description of the problem, I would guess you want the first query to be network-only, but you want to switch back to cache-first for subsequent queries. Thanks to #6712, we now have an easy way to achieve that (namely, the nextFetchPolicy option):

const { data, fetchMore, networkStatus } = useQuery<Todos>(TODOS_QUERY, {
  fetchPolicy: "network-only",
  nextFetchPolicy: "cache-first", // this line
  notifyOnNetworkStatusChange: true,
  variables: {
    options: {
      paginate: {
        page: 0,
        limit: 5
      }
    }
  }
});

Please use nextFetchPolicy instead of monkey-patching fetchMore.

Thank you. I tried this resolution but, try as I may, each fetchMore always hits the network and never hits the cache. Even though I simulated calling it with the same limit and offset variables, and I tried putting them in keyArgs and removing them from there. Nothing works. My use case is a table that fetches more data on scrolling, but that should get the data from the cache when scrolling back upwards.

3reactions
benjamncommented, Feb 16, 2021

@gbiryukov The client is doing exactly what you’ve asked it to do here!

Since fetchMore works by updating the cache, if you want to render those updates without making an additional network request, you need a fetchPolicy that’s allowed to read from the cache, rather than (just) network-only. If you stick with fetchPolicy: "network-only" after the first request, the client’s only option for responding to cache updates from fetchMore is to perform an additional network request. The cache-and-network policy allows reading from the cache, which is a step in the right direction, but it also makes an unconditional network request, so that’s not exactly what you want. Here’s a summary of the history of these behaviors, in case you’re curious: https://github.com/apollographql/apollo-client/issues/6760#issuecomment-668188727

Based on your description of the problem, I would guess you want the first query to be network-only, but you want to switch back to cache-first for subsequent queries. Thanks to #6712, we now have an easy way to achieve that (namely, the nextFetchPolicy option):

const { data, fetchMore, networkStatus } = useQuery<Todos>(TODOS_QUERY, {
  fetchPolicy: "network-only",
  nextFetchPolicy: "cache-first", // this line
  notifyOnNetworkStatusChange: true,
  variables: {
    options: {
      paginate: {
        page: 0,
        limit: 5
      }
    }
  }
});

Please use nextFetchPolicy instead of monkey-patching fetchMore.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Queries - Apollo GraphQL Docs
To guarantee that the refetch performs a network request, its fetchPolicy is set to network-only (unless the original query's fetchPolicy is no-cache or...
Read more >
apollo-client - Awesome JS
Calling fetchMore for queries using the cache-and-network or network-only fetch ... to prevent unnecessary network requests when using a FetchPolicy of ...
Read more >
@apollo/client | Yarn - Package Manager
notifyTimeout in QueryInfo#markResult to prevent unnecessary network requests when using a FetchPolicy of cache-and-network or network-only in a React ...
Read more >
Apollo client fetchPolicy issues - query called twice
If I'm using one of cache-and-network or network-only fetch policies, one of the queries is called twice. This doesn't happen when I use...
Read more >
Merge pull request #801 from zino-app/beta · cf90ec3939
override policies for a single query. client.query(QueryOptions(. // return result from network and save to cache. fetchPolicy: FetchPolicy.networkOnly,.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

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