apollo-client not working as expected for `network-only` cache policy, duplicate requests noticed

Created on 19 May 2020  ·  16Comments  ·  Source: apollographql/apollo-client

Intended outcome:
Network tab doesn't show duplicate query requests

Actual outcome:

Noticed the query being requested for twice
How to reproduce the issue:

Versions
System:
OS: macOS High Sierra 10.13.6
Binaries:
Node: 12.9.1 - /usr/local/bin/node
npm: 6.10.3 - /usr/local/bin/npm
Browsers:
Chrome: 84.0.4143.2
Firefox: 75.0
Safari: 13.1
npmGlobalPackages:
apollo: 3.0.0-beta.45

needs-reproduction

Most helpful comment

I can confirm that this is happening in our application on beta.49 for us as well. We have a code change where all we did was flip our main query from cache-and-network to network-only and this exact problem manifests. No other code changes introduced.

I am sorry I cannot provide a minimum reproduction, but for what it's worth we are using @client directive on the query and are resolving its data via a client-side resolver.

All 16 comments

@mhuconcern Can you provide a small runnable reproduction that shows this? Thanks!

@mhuconcern Actually, one more thing to mention here. Using apollo-link-dedup is no longer required with @apollo/client. Deduplication functionality is built into the core. Can you try removing apollo-link-dedup to see if that helps?

@hwillson I probably should word it correctly but yes we don't use Apollo link dedup seperately :) I thought it was the offending library

I am seeing this as well. The change happened in @apollo/[email protected] and has the same behavior up to @apollo/[email protected].

@apollo/[email protected] does not have the issue.

I will work on unraveling my project a bit and try to create a reproduction.

For what it's worth, I am also getting "No more mocked responses" error for queries and mutations that do not have a fetchPolicy explicitly set. The weird thing is that sometimes just duplicating the mock will "fix" it. Other times, I can create many, many copies of the mock and it will still give the "No more mocked responses" error.

I can confirm that this is happening in our application on beta.49 for us as well. We have a code change where all we did was flip our main query from cache-and-network to network-only and this exact problem manifests. No other code changes introduced.

I am sorry I cannot provide a minimum reproduction, but for what it's worth we are using @client directive on the query and are resolving its data via a client-side resolver.

Are we talking about 'network-only' and 'no-cache' fetching from cache and not executing server requests, right?

If so, I have the same problem for 'network-only' as well as for 'no-cache' with Apollo Client v3.0.0-rc.4.

client.query({ fetchPolicy: 'network-only', query: gql`....` })

If called 3 times, only 1 network call in Chrome's Network tab (and only 1 server log).

Only creating new ApolloClient instances before querying will bypass the cache...

There is something I don't understand from the docs:

network-only: This fetch policy will never return you initial data from the cache.

What is meant by "initial data"? I tried to browse through the doc for its meaning, but it is not clarified.

@thojanssens https://github.com/apollographql/apollo-client/pull/6353 should help explain what you're seeing. no-cache shouldn't be affected by this though; if it is, can you post a small runnable reproduction that shows this?

fetchPolicy: 'no-cache' also executes 1 network request even if I call query 3 times.
I can see 3 logs with the data on the client. Just to make sure, checked the server, and indeed only 1 request received.

It's hard for me to create a runnable; I'd insert fetchPolicy: 'no-cache' to any code that calls query on the ApolloClient instance, call the query multiple times, and look in the console.

I'll get back to you if I find a few hours free to play with some public GraphQL API and an environment without react deps.

Thanks @thojanssens - is the cache empty when you call no-cache the first time?

@hwillson When I tested I was refreshing the page, so the cache was empty as it is in memory. We might use Apollo client when our application will grow; for the moment I will go for simple fetch requests. I'm no longer able to comment on this issue. Thank you

I've been digging through open issues a bit trying to find something similar to what I've been experiencing, and I'd like to suggest that this may be a duplicate of #6301. The reproduction linked and the fix suggested there may be helpful.

In my case I noticed second http request was being made with empty variables when I use fetchMore. I was using network-only as my fetchPolicy since my use-case was fetching paginated list of latest events,
As a workaround, I changed fetchPolicy to cache-first which would make single http request always, and used useEffect to clear related cache on component unmount and refetching data conditionally, as so:

  useEffect(() => {
    if (!loading && data?.events.list.length === 0) refetch();
  }, [loading, data]);
  useEffect(() => {
    return () => {
      client.cache.modify({
        id: 'EventPagination:events#allEvents',
        fields: {
          cursor: () => null,
          hasMore: () => true,
          list: () => [],
        },
      });
    };
  }, []);

minimal reproduction here: codesandbox

Intended outcome:
1 request to /api/graphql when clicking the Fetch More button

Actual outcome:
2 requests to /api/graphql

How to reproduce the issue:
click Fetch More & observe in devtools network tab

I have this issue when using useLazyQuery.

  const [
    loadResults,
    { loading, error, data, fetchMore },
  ] = useLazyQuery(QUERY, {
    variables: {
      q,
      offset,
      rows,
    },
    notifyOnNetworkStatusChange: true,
    fetchPolicy: "network-only",
  });

loadResults() requests just once, but fetchMore (where I give a different offset value) requests twice: first with the new offset given in its options, then with the original offset (0).

Any solution to this?

Was this page helpful?
0 / 5 - 0 ratings