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.

[BUG] FetchMore + fetchPolicy: 'network-only' always triggers first page query

See original GitHub issue

Hi,

Given the situation :

  • Pagination with merge function set in typePolicies from InMemoryCache
...
cache: new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        people: {
          keyArgs: false,
          merge: (existing, incoming, { args }) => {
            const offset = args?.skip || 0;
            const merged = existing ? existing.slice(0) : [];
            for (let i = 0; i < incoming.length; ++i) {
              merged[offset + i] = incoming[i];
            }
            return merged;
          }
        }
      }
    }
  }
}),
...
  • fetchPolicy set with ‘network-only’ or ‘cache-and-network’
const { loading, data, fetchMore } = useQuery(ALL_PEOPLE, {
  variables: { skip: 0 },
  fetchPolicy: 'network-only'
});
  • Call fetchMore from useQuery
<button onClick={() => fetchMore({ variables: { skip: data?.people.length } })}>
  Next page
</button>

Bug : linked query is triggered twice

  • Once with correct pagination variables
  • Once with initial variables

Here a sandbox : https://codesandbox.io/s/black-snowflake-vdhwm

There are some logs showing the linked query fired twice (as the bug description) on “Next Page” click. It doesn’t happen if fetchPolicy is unset.

Thanks for reading.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:15
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

30reactions
benjamncommented, Nov 12, 2020

@jgan42 @CaptainStiggz You may want to switch back to fetchPolicy: "cache-first" after the initial request, since network-only will always go to the network, hence the extra network requests. To to that, use nextFetchPolicy:

const { loading, data, fetchMore } = useQuery(ALL_PEOPLE, {
  variables: { skip: 0 },
  fetchPolicy: 'network-only',
  nextFetchPolicy: 'cache-first',
});
1reaction
jgan42commented, Nov 13, 2020

This seems to be what I need.

I updated the sandbox to work like this :

    typePolicies: {
      Query: {
        fields: {
          people: {
            keyArgs: false,
            merge: (existing = [], incoming, { args }) => 
              args?.skip ? incoming : [...existing, ...incoming]
            },
          }
        }
      }
    }

Moved the list into a subcomponent which can be rerendered.

The original wanted behavior : The user can “infinite scroll in the page”. Then move from the list page, come back and start again with server data from the first page. Now it works.

I did see nextFetchPolicy at one point but it seemed odd to me. Using fetchPolicy: 'network-only' + nextFetchPolicy: 'cache-first' makes me think that the query will only work as “cache-first” only. Because if there is no cache, it surely will get the data from the server the first time. With the sandbox test, It now makes me think that fetchPolicy + nextFetchPolicy will always use the first policy on every new render.

I couldn’t find any documentation about nextFetchPolicy (despite the fact that it exists as “any” value), nor about fetchPolicy but the list which the behaviors aren’t clear to me : "cache-first" | "network-only" | "cache-only" | "no-cache" | "standby" | "cache-and-network"

if @CaptainStiggz can tell if it fills his needs, I will close this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Setting The Correct Fetch Policy - Help - Apollo Community
Throughout the software I use a fetch policy of network-only and a ... + fetchPolicy: 'network-only' always triggers first page query ...
Read more >
Build a paginated list - Apollo GraphQL - w3resource
To build a paginated list with Apollo, we first need to restructure the fetchMore function from the useQuery result object:
Read more >
Is it possible to prevent `useLazyQuery` queries from being re ...
So with a fetchPolicy change of network-only in your example, ... This will prevent the query from firing again after the first fetch....
Read more >
Queries | Documentation - Glimmer Apollo
Queries. In this guide, we look into how to fetch GraphQL data using Glimmer Apollo. It assumes you're familiar with how GraphQL queries...
Read more >
Refreshing Queries - Relay
We are passing a fetchPolicy of 'network-only' to ensure that we always fetch from the network and skip the local data cache.
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