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

useLazyQuery + loading + cache problem with onCompleted? #8775

Open
bunkscene opened this issue Sep 12, 2021 · 3 comments
Open

useLazyQuery + loading + cache problem with onCompleted? #8775

bunkscene opened this issue Sep 12, 2021 · 3 comments
Labels
🔍 investigate Investigate further

Comments

@bunkscene
Copy link

I am using a lazy query with caching. I need to know when the query is complete whether it used the network or the cache.

Here is the basics of the code, which uses cache-first network policy

//manually track loading state
const [isLoading, setIsLoading] = useState(false)

const [loadQuery, { data, error, loading }] = useLoanListLazyQuery({
  onCompleted: data => {
    //when the query is done, turn off manual loading state
    setIsLoading(false)
  },
})

//when the input changes
useEffect(() => {
  //load the data using the query
  loadQuery({ variables: { queryTrigger } })
  //manually turn on loading state
  setIsLoading(true)
}, [queryTrigger])

A working repro of my issue explained below:
https://codesandbox.io/s/apollo-client-beta-fetchmore-bug-forked-k5bip

Steps:

  1. Onload, Count = 3
loadQuery: 3
loading: false
IsLoading: false
loading: true
IsLoading: true
loading: false
Completed: 3 - 1631415455914
IsLoading: false
  1. Set Count = 5 (repro app trigger onchange, so hit backspace and press '5')
loadQuery: 5
IsLoading: true
loading: true
loading: false
Completed: 5 - 1631415463170
IsLoading: false
  1. Set Count = 3 (same as the original, so getting cached data)
loadQuery: 3
IsLoading: true
Completed: 3 - 1631415463456
IsLoading: false

a. Note that loading is no longer changed when retrieving from the cache.
b. The manual isLoading state is still being set correctly.
c. Everything up until this point is ok.

  1. Set Count = 3 (backspace to clear the existing 3, then type 3 again)
loadQuery: 3
IsLoading: true

a. Notice the query is called, the data still displays, but the onCompleted is never called.
b. This feels like a bug to me. I would expect the same output as Step 3.
c. This sample is using 3.5.0-beta12. 3.4.11 shows something different... Step 4 results actually happen in Step 3.
c. Notably, this prevents me from accurately tracking start and end states for the data load.

Does anyone have a good idea on how to reliably know if the data is done being accessed from the cache after a lazy load?

As an addendum, due to other parts of my UI, I do need this loading true->false mechanism, so just displaying the cached data without knowing the start and end state is not an option for me.

@bunkscene
Copy link
Author

Update:

This is the code location:

// No changes, so we won't call onError/onCompleted.
if (
this.previousOptions &&
!this.previous.loading &&
equal(this.previousOptions.query, query) &&
equal(this.previousOptions.variables, variables)
) {
return;
}

I would think that onCompleted should still be called here. Perhaps it could be added as an option?

@brainkim brainkim self-assigned this Sep 20, 2021
@sanex3339
Copy link

@bunkscene do you have any solution for this on your side?

@bunkscene
Copy link
Author

My workaround is to track the previous query in my code to see if it is the same as the new query and if it is, I do not call loadQuery. This works ok, but I do not like it. Even if I didn't need to, I did request a load and if I do, I should be told it is finished.

@hwillson hwillson added the 🔍 investigate Investigate further label May 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔍 investigate Investigate further
Projects
None yet
Development

No branches or pull requests

4 participants