-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
useLazyQuery default options permanently overridden by execute options #11557
Comments
Hey @cjskill 👋 I'd like to ask what your use case is for this particular thing you said:
I'm curious what you're doing with those results and why the distinction is necessary. Could you provide some more info here on what you're trying to accomplish? |
My API response contains a status (pending/success/failure). For the first API call I want to handle each of these statuses respectively:
For all subsequent requests (from polling) I want to handle each of these statuses respectively:
I basically have a sidebar where you can open different items (React components being mounted and unmounted), and when an item is opened I want to check for results. Within each of these items you can mutate the data, which is then received via an async API (polling). But I don't want to handle success/error statuses on mount because every time I switch between items a success message or an error message will show. I only want to show these messages after a mutation has happened -> poll for results -> then display success/error. |
@cjskill I think I have an idea of what you're saying. If I were to restate, that initial request is used to determine the status of the thing you're querying. If its in a certain state ( Does this sound roughly correct? And for this requirement:
I'm guessing you're showing some kind of toast message or something and you want to make sure you only do this the first time it transitions from pending -> success/error correct? Otherwise I could see how this could get very annoying for your users 😆 Assuming yes, I want to challenge your thinking and consider switching around your solution a little bit. Here you're thinking about it in terms of what triggers the query as a means to orient your code around, but as you're seeing, you're running into some technical issues preventing your desired result. To be quite honest, even if we build a way to "reset" that Instead, I'd have you consider thinking about this from the data itself and writing code to orient around that. I think you'll find this lends to a less awkward solution. With this approach, you're reacting instead to changes in your data, rather than the timing of when/where the query completes. Given my understanding of the problem and this way of thinking, I'd switch to a I'd consider using a Here is roughly that idea in code: // I'm going to use a hypothetical query for this situation that contains a `status`
// field that you can check against
const GET_THING = gql`
query GetThing($id: ID!) {
thing(id: $id) {
id
status
}
}
`;
function Thing({ id }) {
const { data, startPolling, stopPolling } = useQuery(GET_THING, { variables: { id } });
const status = data?.thing?.status;
// Here we can use a ref to store the previous status.
// This ensures we only show the success/error toast when we've transitioned
// _from_ the right state
const previousStatusRef = useRef(status);
useEffect(() => {
if (status === 'pending') {
startPolling(1000);
} else if (status === 'success' && previousStatusRef.current === 'pending') {
stopPolling();
showToast('Success!');
} else if (status === 'error' && previousStatusRef.current === 'pending') {
stopPolling();
showToast('Error :(');
}
previousStatusRef.current = status;
}, [status]);
return // ... whatever you show otherwise
} We typically do not recommend doing data syncing in Feel free to arrange the code above however you want, but I wanted to show you the general idea that I'm presenting here. Let me know if this kind of approach works for your use case, and if not, I'd be happy to collaborate further on a solution that works for your use case. |
This is great! Definitely works for my use case. Good to know to rely on the Thank you for the prompt and detailed responses! |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better. |
@cjskill you're very welcome! Glad that works well for you! |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Issue Description
I am using the
useLazyQuery
hook. I want to run this query once on component mount, then handle those results.After a user interaction I want to
startPolling
the same query, but handle those results differently than the results from the component mount query.Since I can't pass an
onCompleted
callback as an argument to thestartPolling
function I am using the default options to declare theonCompleted
callback.However, when I call the
execute
function, the defaultonCompleted
option is overridden with the initial mountonCompleted
option for all subsequent polls.Example:
Console after button click:
Expected Console after button click:
Link to Reproduction
https://codesandbox.io/p/sandbox/apollo-uselazyquery-9lkpv2?file=%2Fsrc%2FApp.js%3A20%2C15-26%2C13&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522cls3ivhee00063b6kqvnhpuhm%2522%252C%2522sizes%2522%253A%255B70%252C30%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522cls3ivhed00023b6ktebjao3a%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522cls3ivhed00033b6k2g6qnuq9%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522cls3ivhed00053b6kim02on3k%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522cls3ivhed00023b6ktebjao3a%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522cls3ivhed00013b6k0f0nbpu1%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522id%2522%253A%2522cls3kikp800023b6kkctn159o%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522initialSelections%2522%253A%255B%257B%2522startLineNumber%2522%253A20%252C%2522startColumn%2522%253A15%252C%2522endLineNumber%2522%253A26%252C%2522endColumn%2522%253A13%257D%255D%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.js%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%252C%2522id%2522%253A%2522cls3ivhed00023b6ktebjao3a%2522%252C%2522activeTabId%2522%253A%2522cls3kikp800023b6kkctn159o%2522%257D%252C%2522cls3ivhed00053b6kim02on3k%2522%253A%257B%2522id%2522%253A%2522cls3ivhed00053b6kim02on3k%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522cls3ivhed00043b6kb4rugoti%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A0%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522activeTabId%2522%253A%2522cls3ivhed00043b6kb4rugoti%2522%257D%252C%2522cls3ivhed00033b6k2g6qnuq9%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522cls3ivhed00033b6k2g6qnuq9%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D
Reproduction Steps
Open console, click Start polling button.
Observe in the console that the
onCompleted
default callback is overridden by theexecute
onCompleted
callback for every subsequent query.@apollo/client
version3.9.2
The text was updated successfully, but these errors were encountered: