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
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.
bump
Same problem with apollo client 2.2.7. At least i'm not the only one struggling with this problem
/label has-reproduction
Any update on this issue?
you could use the startPolling
and stopPolling
functions.
https://www.apollographql.com/docs/react/essentials/queries.html#refetching
Also hitting this issue
I also have this issue with the VUE implementation of Apollo I'm assuming its a limitation of the core Apollo client.
as @littletower mentioned if you call stopPolling before updating variables and then enable polling again - everything will work fine.
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!
Can we revisit this issue? I have a dynamic variable that needs to be set at each pollingInterval
.
+1
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,
})
}
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.
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,
});
@yuval-hazaz how are you updating the variables? Is there something magic happening in setParam
?
Setting notifyOnNetworkStatusChange: true
fixed this issue for me:
const date = new Date().toISOString()
const result = useQuery(QUERY, {
notifyOnNetworkStatusChange: true,
variables: {
date,
},
pollInterval: POLL_INTERVAL,
})
@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.
Most helpful comment
Can we revisit this issue? I have a dynamic variable that needs to be set at each
pollingInterval
.