Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable recalculation for each polling request #3053

Closed
adam-bernau opened this issue Feb 21, 2018 · 19 comments
Closed

Variable recalculation for each polling request #3053

adam-bernau opened this issue Feb 21, 2018 · 19 comments
Labels
🚧 in-triage Issue currently being triaged

Comments

@adam-bernau
Copy link

Intended outcome:
Use query polling option and recalculate variables for every request.

Actual outcome:
We have a time deppendend query variable, this variable is not propagated from the props, but it is calculated from current time in the query options function. But it's not recalculated when a new polling request is throwed. Is there a way how to enforce variables recalculation please?

const config = {
 options: (props) => {
     const { base } = props;
     // a dynamic variable calculated from current time, it is not recalculated
     const  from =  new Date().getTime() - base; 
     const variables = { from};
     const pollInterval = 5000;
     return { variables, pollInterval };
  }
};

How to reproduce the issue:
https://codesandbox.io/s/q3mjxyw7zw
I tried to simplify the issue and create a simple config with a current time dependend variable.
This variable is not recalculated.

Version

  • apollo-client@2.2.5
@Forfold
Copy link

Forfold commented Feb 27, 2018

I'm also running into this issue. I calculate a variable based on certain parameters and am struggling to find a way to update the initial variables that polling uses if it changes.

Calling updateQuery doesn't seem to have the ability to update the variables as mentioned, either, which at first glance I thought it may be able to.

It looks like the function i use to calculate the property is being called and returning the correct variables (from inside options), but the polling query is still using the stale data from when the page was first loaded.

edit: relevant code to clarify

function getFoo () {
   ...
   return foo // returning correct value on new poll cycle
}


@graphql(query, {
  options: props => {
    return {
      variables: {
        foo: getFoo(),
        ...
      }
   },
   ...
})

But the network tab is using the original value of foo from the initial page load.

@Forfold
Copy link

Forfold commented Mar 6, 2018

bump

@gitupiikki
Copy link

Same problem with apollo client 2.2.7. At least i'm not the only one struggling with this problem

@Trancever
Copy link

/label has-reproduction

@ghost ghost added the has-reproduction label Mar 20, 2018
@Forfold
Copy link

Forfold commented May 7, 2018

Any update on this issue?

@stefanoTron
Copy link

you could use the startPolling and stopPolling functions.
https://www.apollographql.com/docs/react/essentials/queries.html#refetching

@abeaclark
Copy link

Also hitting this issue

@codenamezjames
Copy link

I also have this issue with the VUE implementation of Apollo I'm assuming its a limitation of the core Apollo client.

@healqq
Copy link

healqq commented Jun 19, 2019

as @littletower mentioned if you call stopPolling before updating variables and then enable polling again - everything will work fine.

@jbaxleyiii jbaxleyiii added the 🚧 in-triage Issue currently being triaged label Jul 9, 2019
@jbaxleyiii
Copy link
Contributor

Thanks for reporting this. There hasn't been any activity here in quite some time, so we'll close this issue for now. If this is still a problem (using a modern version of Apollo Client), please let us know. Thanks!

@ethanIncentify
Copy link

Can we revisit this issue? I have a dynamic variable that needs to be set at each pollingInterval.

@yussinsharp
Copy link

+1

@kjellski
Copy link

kjellski commented Apr 27, 2020

I would like to see how it should be done as well, this is the workarround I implemented for us using hooks, maybe that helps getting inspired :) - https://gist.github.com/kjellski/42ae99e7b1d85a76d835274c255c6af0

// NOTE: not using poll here because the interval needs to change on every call.
// So we're using multiple hooks to achieve this:
// 1. `useInterval` to keep the recalculation with `setVariablesIntervalCallback` triggering
// 2. `useState` to have a clear state change when we called `setVariablesIntervalCallback`
// 3. `usePrevious` to have data while new data is beeing fetched so the table can stay intact
const Container = ({ children, someValue }) => {
  const [variables, setVariables] = useState({
    someValue,
    value: calculateValue(),
  })

  const setVariablesIntervalCallback = useCallback(() => {
    setVariables(variables => ({
      ...variables,
      value: calculateValue(),
    }))
  }, [setVariables])

  useInterval(setVariablesIntervalCallback, POLL_INTERVAL_IN_MS)

  const { data, loading, error } = useErrorHandlingQuery(
    queryHubViewDashboard,
    {
      skip: !hubId,
      variables,
    },
  )

  const previousData = usePrevious(data)

  return children({
    // we only want the last fetched data if there's no new one, this is helping while refetching to still fill the UI
    data: data || previousData, 
    loading,
    error,
  })
}

@BenChirlinn
Copy link

BenChirlinn commented Aug 27, 2020

Feels like onCompleted should fire after each polling request is completed but that doesn't seem to be the case? I'm storing the current date in a useRef hook which is then passed as a variable to my useQuery hook. However updating the ref in onCompleted seems to only occur once (I'm guessing after the first successful query).

Edit: I ended up also doing a hacky fix using useInterval hook in combination with the useLazyQuery hook. Set up the lazy query, then in useInterval I call it with the latest date as a variable.

const [fetchQuery, { loading, data }] = useLazyQuery<
    MyQuery,
    MyQueryVariables
  >(myQuery, {
    fetchPolicy: "network-only",
    query: myQuery,
  });

  useInterval(() => {
    if (!shouldISkip) {
      return;
    }

    const dateVar = new Date();
    getStreamHealth({
      variables: {
        userID : userID || "",
        dateVar : dateVar .toISOString(),
      },
    });
  }, FETCH_INTERVAL);

Note I'm doing all this in a custom hook that feeds a context with the latest polled result.

@yuval-hazaz
Copy link

In order ro work around the issue I am using stopPolling then refetch on every parameter change, and then onCompeletd with startPolling

const handleParamChange = (value: string) => {
    setParam(value);
    stopPolling();
    refetch();
  };

   const {
    data,
    refetch,
    stopPolling,
    startPolling,
  } = useQuery(QUERY, {
    onCompleted: () => {
      startPolling(POLL_INTERVAL);
    },
    variables: {
      param: param,
  });

@BenChirlinn
Copy link

BenChirlinn commented Sep 11, 2020

@yuval-hazaz how are you updating the variables? Is there something magic happening in setParam?

@crhallen
Copy link

crhallen commented Nov 26, 2020

Setting notifyOnNetworkStatusChange: true fixed this issue for me:

const date = new Date().toISOString()

const result = useQuery(QUERY, {
  notifyOnNetworkStatusChange: true,
  variables: {
    date,
  },
  pollInterval: POLL_INTERVAL,
})

@CurtainUp
Copy link

@crhallen I found that fixed the issue and let me use my incremented pollInterval using an onCompleted function but now the component is flashing every single time it fires.

@jeff3dx
Copy link

jeff3dx commented Jan 12, 2022

@jbaxleyiii Since this issue has not been resolved in 4 years I will assume Apollo client intends to provide only a toy polling feature. The workarounds are awkward and cannot possibly be intended. For a proper polling feature look at react-query which has the full polling lifecycle built in including variable updates, suspend and restart on window blur/focus, etc.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🚧 in-triage Issue currently being triaged
Projects
None yet
Development

No branches or pull requests