-
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
lazyQuery - double network call #9448
Comments
I've encountered the same issue.
|
same for me |
Same here, also using useLazyQuery on @apollo-client version 3.5.9 |
I'm using version |
We've merged |
@apollo/client": |
encountering the same issue still on |
Second run:
In this scenario I see two request to DB. First one is cancelled ( with search ), second is ok (without search). Adding condition in useLazyQUery for variables solves the problem, and i see always only one call: export function useLazyQuery(query, options) {
var _a;
var execOptionsRef = useRef();
var optionsRef = useRef();
var queryRef = useRef();
var merged = execOptionsRef.current ? mergeOptions(options, execOptionsRef.current) : options;
/**SWEET**/
if (options.variables) {
merged.variables = options.variables
}
var document = (_a = merged === null || merged === void 0 ? void 0 : merged.query) !== null && _a !== void 0 ? _a : query;
optionsRef.current = merged;
queryRef.current = document; It looks like merge options in second call merge old options ( with search ) then call again without. |
In any sort of authentication flow this is a big deal, where we Still having this issue with version: Below is example snippet of calling a useLazyQuery function const [login, { error, loading }] = useLazyQuery(LOGIN, {
fetchPolicy: 'no-cache',
});
const onSubmit = async (values) => {
const formIsValid = isValid(values);
if (formIsValid) {
return await login({
variables: {
credentials: {
username: values.username,
password: values.password,
},
},
});
}
}; Proof from Chrome Network tab that the call is being made twice: |
Disregard ^^^, went digging in client, and found the way I had set up my link chain, forwarding an operation in an invalid location was the issue. |
Hey all 👋 We'd greatly appreciate a reproduction of this issue to dig in further. We had a number of fixes for You can use our error template as a starting point or send us a Replay of the issue which would help tremendously. Thanks! |
It seems to be fixed on |
I have updated version from
|
@asvetlenko We cannot reproduce this and really need to see this with our own eyes. Please create a reproduction or a Replay. You can use our error template as a starting point or send us a Replay of the issue which would help tremendously. Thanks! |
@sa-ma thanks for the Replay! Since that link is public I'll delete your original comment out of caution and copypaste just the text below:
|
@sa-ma, just to be on the safe side, could you please set the Replay to "private" and share it with |
I will. Thanks. |
Hi, Is there any update on this or has anyone found a workaround? |
@sa-ma in your case, I could find the error, and it seems to be on your side: Your |
In my case, useLazyQuery called twice when I delete one of the existing query variables:
But how to fix it IDK, coz GQL do not allow empty object variables ( filter: {} ) |
@palyvodaBoi could you please create a reproduction for this? This has been extremely hard for us to reproduce, and we really need to see this happening. |
@phryneas, thank you for your quick response. It's the same tough for me to create a Jsfiddle with an example. Do you have a playground? |
@palyvodaBoi you can use this as a starter: https://codesandbox.io/s/github/apollographql/react-apollo-error-template |
@phryneas it was working, but now: Maybe i can show my component and Apollo setup here? |
@palyvodaBoi We really need to see this running - at this point, I've tried to reproduce this at least five times. |
@phryneas thanx a lot! Finally, it works for me. Here is the branch with my setup and changes (only There are 2 buttons fetching data with useLazyQuery |
@palyvodaBoi thanks so much for that reproduction! This is extremely helpful. From what I've observed, it looks like this becomes an issue when you start with variables, then call it again without any variables. If you start by clicking the 2nd button (as many times as you want), you'll see a single network request issued. Clicking the 1st button also issues a single request. Its only after you click the 2nd button again after you've set variables that the issue shows up. This is definitely a huge clue as to what might be happening here. Thank you so much for the help! We will see if we can get a fix in here soon 🙂 Edit: I've got a failing test that reproduces this in #11403 |
@palyvodaBoi if you need a workaround, you can fix the double request by setting that variable value to const [fetchFilms] = useLazyQuery(query)
// first click
fetchFilms({ variables: { filmId: 'ZmlsbXM6MQ==' })
// second click
fetchFilms({ variables: { filmId: undefined } }) // undefined removes the filmId key in the request This bug in particular gets a bit tricky due to the mechanics of Take this example: const [getFilms] = useLazyQuery(GET_FILMS, { variables: { id: '1' })
// Should fetch the film with id = 1. No variables passed
getFilms()
// Should fetch the film with id = 2 because we are changing variables
getFilms({ variables: { id: '2' } }) The question then becomes, what happens if I call getFilms() Should this fetch with I'd argue the right behavior here is that it should try again with That brings up this current bug. If this behavior becomes the rule (merge variables and use the last set value), this means you won't be able to "clear" a value just by calling the function again. fetchFilms({ variables: { id: '1' })
fetchFilms() // should try again with id '1' To me, fixing this bug would mean executing the query with the last set variables again. To "clear" that variable value and avoid it getting sent to the server, you'd need to pass fetchFilms({ variables: { id: undefined }) This would ensure that we maintain a consistent behavior no matter how or where those variables were set. Calling the execute function without variables essentially just becomes a "don't override what I set last time". Does this behavior make sense to you if we end up fixing this bug in that manner? |
@jerelmiller, i appreciate your support and quick response! Thanx again :) in my opinion, it is more logical that |
Thing about "undefined" is that you need to keep your variables and mapping (put undefined) them everytime they are changed :/ if you put some variable and don't need it more you need to set it to undefined. What about something like: |
@mrocznyKucykZaglady its an interesting idea, but unfortunately I think that would be too much of a breaking change to consider in 3.x. We've allowed the ability to merge On the flip side, even if we decided to move forward with this, this would mean you'd need to keep an entire mapping of your variables somewhere, which may end up being more cumbersome than just setting the variable you'd like to remove to I think the fix here is just to make sure that calling the execute function with no arguments would send the last used variables and avoid the double call. |
Hey all 👋 I believe I've solved this with #11403. We will try and get this pushed out in the next patch version or so. If you'd like to try out the snapshot release, you can install it with the following:
Looking forward to closing the loop on this one! |
After a big more digging at historical behavior on how variables merging works, @palyvodaBoi's opinion was the right one:
My original comment goes to show how our documentation was a bit ambiguous on this topic and how I've always thought about this hook in the wrong way. @phryneas and I took a dive into early versions of 3.x to verify how the original intended behavior. In versions 3.0.0 and onward until this bug was introduced, variables merging was done by taking the variables passed to the hook and merging it with the variables passed to the execute function. This means that if you do not pass variables to the execute function, the only variables sent with the request are the ones passed to the hook itself. #11403 fixes the double network request and ensures the variable merging behavior works as originally intended. I've added a note in our docs to try and clarify this point to avoid ambiguity going forward. |
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. |
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. |
Hi
I have updated my
@apollo/client
from 3.50 to the latest release 3.5.8and I have an issue with the lazyQuery, which creates double network calls:
Example
When running this useEffect hook, I see the console log message issued only once. However, the server executes the
query twice in the DB and I see two network calls in the browser inspect
OPTIONS OPTIONS FETCH FETCH
and following these, 2 queries in the DB.
I tried to use fetchingPolicies but without any success
when I downgrade to 3.5.0 then it works as expected
The text was updated successfully, but these errors were encountered: