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.

onCompleted not called after skip is set to false and the data is cached

See original GitHub issue

Consider this code (useQuery with a skip condition):

const { loading, data } = useQuery(MY_QUERY, {
  skip: condition,
  onCompleted: response => { /* Handle the response */ },
});

Intended outcome: onCompleted should be called after the data has been fetched, either from the server or from the cache.

Actual outcome: onCompleted is called only when the data is fetched from the server and not when it is fetched from the cache.

How to reproduce the issue: https://codesandbox.io/s/apollo-query-skip-bug-x60ht (This codesandbox example fetches data from https://graphqlzero.almansi.me/api)

  1. Click on the Show Page button.

That will mount the <Page /> component, which contains this code:

 const { loading, data } = useQuery(USERS_QUERY, {
   skip: skipper,
   onCompleted: response => {
     setUserList(response.users.data);
   },
 });

 console.log(data);

You will see the value of data in the console output. It is undefined.

  1. Click on the Start Fetching button.

That will set the value of skipper to false. The query will be executed and onCompleted will be called. You will see the value of data in the console output. This time it won’t be undefined. It will be an Object. You will also see the fetched data displayed inside the <Page /> component, and that is because the onCompleted handler changed the state of the component.

  1. Click on the Hide Page button.

That will unmount the <Page /> component

  1. Click on the Show Page button.

That will mount the <Page /> component again, and the value of data in the console output is undefined.

  1. Click on the Start Fetching button.

This time the query will fetch the data from the cache. onCompleted won’t be called, but you can see the value of data in the console output, and it is an Object.

Versions System:   OS: Windows 10 10.0.19041 Binaries:   Node: 12.18.3 - C:\Program Files\nodejs\node.EXE   npm: 6.14.6 - C:\Program Files\nodejs\npm.CMD Browsers:   Chrome: 87.0.4280.88   Edge: Spartan (44.19041.423.0), Chromium (87.0.664.66) npmPackages:   @apollo/client: ^3.3.6 => 3.3.6   apollo-upload-client: ^14.1.2 => 14.1.2

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:4
  • Comments:6

github_iconTop GitHub Comments

1reaction
krspvcommented, Feb 24, 2021

This is a big problem! It’s breaking the API contract that says the function is going to be called when the fetch completes. This makes our progress bars to hang, and it is ridiculous that Apollo does not abstract us from this. What is the alternative? Some weird timeout functions that automatically clear the state ? I can’t believe nobody else is complaining about this

I don’t use onCompleted any more. I do it like this now:

  const { data } = useQuery(MY_QUERY);
  useEffect(() => { // onCompleted workaround
    if (data != null) {
      // Do your stuff here!
    }
  }, [data]);
1reaction
danielo515commented, Feb 24, 2021

This is a big problem! It’s breaking the API contract that says the function is going to be called when the fetch completes. This makes our progress bars to hang, and it is ridiculous that Apollo does not abstract us from this. What is the alternative? Some weird timeout functions that automatically clear the state ? I can’t believe nobody else is complaining about this

Read more comments on GitHub >

github_iconTop Results From Across the Web

onCompleted callback is not calling for 2nd ... - Stack Overflow
It seems to be a known issue that Apollo's onCompleted option works differently between queries fulfilled over the network and by the cache....
Read more >
Refetching queries in Apollo Client - Apollo GraphQL Docs
Local cache updates and refetching work especially well in combination: your application can display the results of local cache modifications immediately, while ...
Read more >
useQuery | TanStack Query Docs
If set to false , the query will not be retried on mount if it contains an ... When a query's cache becomes...
Read more >
Calling Queries Manually with useLazyQuery - Thinkster.io
This is fine for such a small data set, but what if we had hundreds of habits with hundreds of entries? It might...
Read more >
graphql-hooks - npm
The first thing you may ask when seeing graphql-hooks is "Why not use Apollo ... Set to false if you wish to skip...
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