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
notifyOnNetworkStatusChangetotruesolved the issue in my case.Also, @dominik-myszkowski , setting
fetchPolicy: 'network-only'only triggers theonCompletedonce. I can only get it working by settingnotifyOnNetworkStatusChange: trueThis 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
onCompletedis 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'theonCompletedhandler is only being called once.Right, absolutely, it should! That’s the bug. I’ve commented merely to point out that setting
notifyOnNetworkStatusChangeisn’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
notifyOnNetworkStatusChangeis 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.
notifyOnNetworkStatusChangeis 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
pollIntervalto 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, butonCompletedonly runs once. As other have mentioned,notifyOnNetworkStatusChange: truecausesonCompletedto rerun.The fact that
onCompletedruns only once is unintuitive and undesireable. The fact that its fixed by setting a seemingly unrelated optionnotifyOnNetworkStatusChangechanges 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: truefixes 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
useQueryinto a dead end of the tree, so the rerendering isn’t annoying. In there I then usemakeVarwhich is then used in thetypePoliciesof 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.