apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

query with pollInterval does not skip once polling has started #7552

Open watadarkstar opened 3 years ago

watadarkstar commented 3 years ago

Intended outcome:

I had an Apollo query that was polling for unread direct messages and skipping the polling if the userId was undefined.

const { data: unreadDmData } = useGetUnreadDmChatsQuery({     
    fetchPolicy: 'cache-and-network',    
    skip: !userId,      
    pollInterval: UNREAD_DM_POLL_INTERVAL,  
})

Actual outcome:

However, when users logged out this global polling mechanism was still polling even when the skip condition was not met.

How to reproduce the issue:

To reproduce you need a query with a pollInterval and a skip condition that is met and then at some point later is no longer met. The polling will continue even after the skip condition is false.

const { data: unreadDmData } = useGetUnreadDmChatsQuery({     
    fetchPolicy: 'cache-and-network',    
    skip: !userId,      
    pollInterval: UNREAD_DM_POLL_INTERVAL,  
})

Workaround

There is a workaround and that is to call stopPolling when the condition is not met inside a useEffect that checks if the skip condition is not met.

i.e.

 useEffect(() => {
    if (!userId) {
      stopPolling()
   } else {
       startPolling(UNREAD_DM_POLL_INTERVAL)
   }
})

Versions

System: OS: macOS 10.15.7 Binaries: Node: 14.7.0 - ~/.nvm/versions/node/v14.7.0/bin/node Yarn: 1.22.4 - ~/.yarn/bin/yarn npm: 6.14.7 - ~/.nvm/versions/node/v14.7.0/bin/npm Browsers: Chrome: 87.0.4280.88 Firefox: 81.0.2 Safari: 14.0 npmPackages: @apollo/client: ^3.2.9 => 3.2.9 apollo3-cache-persist: ^0.9.1 => 0.9.1

alicerocheman commented 2 years ago

Hello,

I'm on appollo client 3.5.6 and I'm still encountering this issue, even though the fix was apparently merged into 3.4

Even with the workaround in place:

  useEffect(() => {
    if (skip) {
      stopPolling();
    } else {
      startPolling(POLL_INTERVAL);
    }
  }, [skip, stopPolling, startPolling]);

I still have a query failing in the console when skip turns true, query for which the non-nullable variable myVar is null.

I also tried:

  const pollInterval = useMemo(
    () => (skip ? undefined : POLL_INTERVAL),
    [skip]
  );

It didn't work either.

Only with both fixes does it seem to work:

  const skip = useMemo(() => !myVar, [myVar]);

  const variables = useMemo(() => ({ myVar }), [myVar]);

  // set pollInterval to undefined when skip is true
  const pollInterval = useMemo(
    () => (skip ? undefined : POLL_INTERVAL),
    [skip]
  );

  const {
    data,
    startPolling,
    stopPolling,
  } = useQuery(MyQuery, {
    fetchPolicy: 'network-only',
    pollInterval,
    skip,
    variables,
  });

  // stop/start polling
  useEffect(() => {
    if (skip) {
      stopPolling();
    } else {
      startPolling(POLL_INTERVAL);
    }
  }, [skip, stopPolling, startPolling]);
SugarDarius commented 2 years ago

Hello Apollo team ! The fix doesn't work on my side neither :/

@apollo/client: 3.5.9

I have no specific config into the apollo client definition file. Here's my query :

 const skip = !isMyVarTrueOrFalse
 const { data } = useQuery(MyQueryDocument, {
     variables: { ...myVariables },
     skip,
     pollInterval: 0
})

I can see into the network of my Chrome console that event when skip is set to true, a request is made so to me the query is well executed.

If you have any hints or workarounds it would be very helpful 🙏🏻 Many thanks 😄

Sh1d0w commented 1 year ago

Any progress on this? It is still happening 3 years after reporting it ...