apollo-client: Using useQuery with pollInterval triggers onCompleted only once
Intended outcome:
I would expect the onCompleted
callback to be fired after every poll.
Actual outcome:
onCompleted
is being fired only once. First time the query is made.
How to reproduce the issue:
const { data, stopPolling } = useQuery(QUERY, {
variables: {...},
fetchPolicy: 'network-only',
pollInterval: 1000,
onCompleted: () => console.log('called')
})
Versions
npmPackages: @apollo/react-common: ^3.0.1 => 3.0.1 @apollo/react-hooks: ^3.0.1 => 3.0.1 apollo-cache-inmemory: ^1.3.5 => 1.3.11 apollo-client: ^2.6.4 => 2.6.4 apollo-link: ^1.2.3 => 1.2.4 apollo-link-context: ^1.0.10 => 1.0.10 apollo-link-error: ^1.1.1 => 1.1.2 apollo-link-http: ^1.5.5 => 1.5.7 apollo-link-logger: ^1.2.3 => 1.2.3 apollo-server-koa: ^2.1.0 => 2.2.4 apollo-utilities: ^1.3.2 => 1.3.2 react-apollo: ^2.2.4 => 2.3.2
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 48
- Comments: 42 (7 by maintainers)
Commits related to this issue
- Reproduce issue https://github.com/apollographql/apollo-client/issues/5531 — committed to dylanwulf/react-apollo-error-template by dylanwulf 3 years ago
- add a test to make sure pollInterval triggers onCompleted Confirms #5531 is fixed. — committed to apollographql/apollo-client by brainkim 3 years ago
- add a test to make sure pollInterval triggers onCompleted Confirms #5531 is fixed. — committed to apollographql/apollo-client by brainkim 3 years ago
- add a test to make sure pollInterval triggers onCompleted Confirms #5531 is fixed. — committed to apollographql/apollo-client by brainkim 3 years ago
- add a test to make sure pollInterval triggers onCompleted Confirms #5531 is fixed. — committed to apollographql/apollo-client by brainkim 3 years ago
- add a test to make sure pollInterval triggers onCompleted Confirms #5531 is fixed. — committed to apollographql/apollo-client by brainkim 3 years ago
Setting
notifyOnNetworkStatusChange
totrue
solved the issue in my case.Also, @dominik-myszkowski , setting
fetchPolicy: 'network-only'
only triggers theonCompleted
once. I can only get it working by settingnotifyOnNetworkStatusChange: true
This issue persists in
3.5.8
.It’s baffling how issues like this can go multiple years without being addressed in such a widely used library… And this is not the first one I’ve seen.
I suggest reopening this issue.
This should now be resolved in
@apollo/client@3.5.0
. Let us know if you notice any issues. Thanks!@ajhool I have just tested it again and I can confirm that the query is being called multiple times. I can see it in the network traffic every second, but the
onCompleted
is being called only once.I created a runnable reproduction of this issue (use branch
polling-oncompleted-not-called
): https://github.com/dylanwulf/react-apollo-error-template/tree/polling-oncompleted-not-calledThis worked for me. Setting ‘network-only’ did not.
I’m running into this issue as well. Even with
fetchPolicy: 'no-cache'
theonCompleted
handler is only being called once.Right, absolutely, it should! That’s the bug. I’ve commented merely to point out that setting
notifyOnNetworkStatusChange
isn’t a workable workaround in many situations and that folks should be aware of that drawback before applying it willy nilly, as it causes the whole tree below the hook to rerender on every interval.The issue with setting
notifyOnNetworkStatusChange
is that it will rerender for every poll interval (as documented). This is probably not what you want and you’d want to rerender only when the data changes.This could be the culprit?
https://github.com/apollographql/apollo-client/blob/6bc9fdcfc064bd60533794f0ef5aeed45f7ad537/src/react/data/QueryData.ts#L433
It seems onCompleted only runs when data has changed, so if you are polling and no data changes occur then it will not fire.
Ideally there could be an extra prop to always call. Or maybe an alternative function prop,
onCompletedAlways
?Yup, can confirm. Still happening in
3.3.6
. I resolved the issue withnotifyOnNetworkStatusChange
, though it’s like using a baseball bat to clean the dishes.The only other alternative I can come up with is using a
useEffect
, andrefetch
.same issue, in addition to onCompleted, my react table is not reflecting changes even though i see the calls in network.
notifyOnNetworkStatusChange
is making everything re-render on each poll so that’s not really a solution i can use.A workaround for our case was to add
fetchPolicy: 'no-cache',
to the query options. Thus:Obviously this means you will bypass the client-side cache but it will ensure the completion hook is triggered every time.
@akikoskine, @brainkim, can we reopen this issue?
The same is true for
onError
. It’s called for the first error but is not called if later poll attempts have errors. The workarounds do not help me.Bumping this because I ran into it. I was using
pollInterval
to check on a job, and set it to zero once the job is done (since there won’t be any updates afterwards). I havefetchPolicy: "no-cache"
and the data I fetch definitely changes, butonCompleted
only runs once. As other have mentioned,notifyOnNetworkStatusChange: true
causesonCompleted
to rerun.The fact that
onCompleted
runs only once is unintuitive and undesireable. The fact that its fixed by setting a seemingly unrelated optionnotifyOnNetworkStatusChange
changes the behavior is very unintuitive.@alessbell @hwillson @ajhool Please consider this useCase.
fetchPolicy is
cache-and-network
. Query goes and data is present in cache. onCompleted is called.Simultaneously Network call goes (Because fetchPolicy is
cache-and-network
). In the network call, data has changed which causes cache to update BUT, onCompleted will never be called with this new data. Isn’t this not a valid usecase where onCompleted should have been called?Additional: onCompleted won’t be called the second time because of this check ->
previousResult?.networkStatus !== result.networkStatus
. networkStatus doesn’t change in our above useCase when cache is revalidated with network request.Please check
This has proven to be the most reliable combination for us. note the separate user queries and the manual starting and stoping of polling. this bypasses a second bug in which stop polling does not reliably work with pollinterval
I don’t think this is fixed @hwillson
Here’s a codesandbox repro. Making
notifyOnNetworkStatusChange: true
fixes it (as it always did), but when it’s false, the original issue still exists.Should this be re-opened?
For what it’s worth, I’ve sort of resolved the issue caused by this workaround for the time being by chucking the polling
useQuery
into a dead end of the tree, so the rerendering isn’t annoying. In there I then usemakeVar
which is then used in thetypePolicies
of the InMemoryCache, like this:It’s quite the detour, but it works, so hopefully it’s useful for someone else too.
Have you checked the network traffic? I believe that it does not actually poll, as opposed to executing onComplete only on the first query.