Intended outcome:
skip: true
results in no network request.
The error
property in the result of the useQuery hook reflects the current running query.
Actual outcome:
skip: true
results in a network request.
The error
property displays for the previous result.
How to reproduce the issue:
1) Go here: https://codesandbox.io/s/apolloclient-v3-skip-bug-ov1z3?file=/src/app.js
2) Click the button and observe the 400
from the graphql endpoint.
3) Click the button again and observe the successful response but the logged error message.
Related Issues
https://github.com/apollographql/apollo-client/issues/6190
https://github.com/apollographql/apollo-client/issues/6572
https://github.com/apollographql/apollo-client/issues/6507
I traced all the way into the fetchQueryByPolicy function introduced in #6221. I believe it has something to do with the skip option not being passed to the resultsFromLink
call:
I tried locally modifying this but even when passing skip
the network request is still made.
@benjamn I'd like to learn more about the inner-workings of ApolloClient, and would be happy to try and fix this but I'm not sure what I'm looking for. I know the options are differing here, with skip: true
being in the new options:
which calls to update the "current observable" on the query data class. I'm guessing that for some reason the thing that makes fetch/no-fetch decisions is not aware of this update.
I'm having this same problem.
Is this a duplicate of https://github.com/apollographql/react-apollo/issues/3492#issuecomment-644385154? Also related: https://github.com/apollographql/apollo-client/issues/6342
Is this a duplicate of apollographql/react-apollo#3492 (comment)? Also related: #6342
Maybe? I wanted to create an issue with very simple/specific repro.
Okay so skip
has been not working for a while. This comment fixed it for me, until a new version is released:
It actually broke in 3.0.0-beta.46. Last working release is 3.0.0-beta.45!
i'm surprised the major release (out of beta) was done with this still broken (since it was a known thing not a bug that popped after release).. it's a pretty widely used feature and I was a little shocked after I migrated to find the console error and this thread .. would of been nice if it was a known thing to make mention of it in the release/migration guide .. maybe its just me though?
Funnily enough we migrated back to beta-43. It's more stable as of the moment of writing
@3nvi is there any other things I should keep an eye on based on your comment sounds like there might be other unmentioned issues? .. we've been QA'ing the migration to 3.0.2 but a heads up if you know of anything specific would be great!
@3nvi is there any other things I should keep an eye on based on your comment sounds like there might be other unmentioned issues? .. we've been QA'ing the migration to 3.0.2 but a heads up if you know of anything specific would be great!
https://github.com/apollographql/apollo-client/issues/6603
https://github.com/apollographql/apollo-client/issues/6644
https://github.com/apollographql/apollo-client/issues/6636 (fixed in upcoming 3.1.0.)
related to #6572
If anyone needs a work around, this is what I came up with.
import { OperationVariables } from '@apollo/react-common';
import { DocumentNode } from 'graphql';
import { useEffect } from 'react';
import { useLazyQuery, LazyQueryHookOptions } from '@apollo/react-hooks';
const useSkippableQuery = <TData = any, TVariables = OperationVariables>(
query: DocumentNode,
options: LazyQueryHookOptions<TData, TVariables> & { skip: boolean }
) => {
const { skip, ...rest } = options;
const [lazyQuery, result] = useLazyQuery<TData, TVariables>(query, rest);
useEffect(() => {
if (!skip) lazyQuery();
}, [skip]);
/* On the first render cycle, lazy query always returns loading false because the useEffect has
* not yet invoked the query. This ensures that the loading will be true on the first cycle
* by checking the skip prop directly and checking the query has been called */
const loading = result.loading || (!skip && !result.called);
const data = !skip ? result.data : undefined;
return { ...result, data, loading };
};
export default useSkippableQuery;
You can then use this pretty much like useQuery
and provide the skip
prop. It's not heavily tested but I think gets the job done.
@s-taylor nice hook! I was going down the route of switching us to lazy query with effects/skip flags but I got hung up on the initial loading state. I'll give this hook a shot :) Thanks for the suggestion!
Edit: @s-taylor, oops, forgot that data
is switched to undefined
when skip
toggles from false
to true
. You'll want to add something like:
const data = !skip ? result.data : undefined;
return { ...result, data, loading };
Edit 2: We need to pass variables to the invoker since the variable can change between renders, but for some reason, passing the variables to the effect cause an infinite loop. :/
const { skip, variables, ...rest } = options;
const [runQuery, result] = useLazyQuery(query, rest);
useEffect(() => {
if (!skip) {
runQuery({
variables
});
}
}, [runQuery, skip, variables]);
as a workaround, you might want to try this https://github.com/apollographql/apollo-client/issues/6572#issue-655006495
You don't need to use useEffect nor useLazyQuery and avoid having 2 render cycles
TLDR
const skip = !company;
const variables = !skip
? {
companyId: company.id,
}
: {};
const { data, loading } = useQuery({
variables,
skip,
});
@tafelito does not work for us - query is still invoked when skip
toggles from false
to true
.
@sirugh nice thanks! I will update the snippet.
One flaw I've found with my approach though, is that once skip has been set to false
and the lazy query has been triggered, it seems like the lazy query is always re-fired on a re-render. I guess this is the lazy query behaviour, but this is a problem for us as we sometimes want the query to go back to being skipped.
We're finalizing a fix for this and other skip
related issues, and should have it ready today.
@sirugh would you be able to verify if @apollo/[email protected]
fixes your original issue?
@hwillson I'll give it a check after my morning meetings. Can you give me about two hours? If you publish pre's to npm you could also check the sandbox quickly, I believe.
Edit: Looks like you guys do, and looks like it did fix the issue in the sandbox. As discussed on the PR, data is being returned now when skip: true
, but at least no network request is made.
Most helpful comment
We're finalizing a fix for this and other
skip
related issues, and should have it ready today.