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

fetchMore from useLazyQuery doesn't include cache changes? #11276

Open
mbiggs-gresham opened this issue Oct 6, 2023 · 5 comments
Open

fetchMore from useLazyQuery doesn't include cache changes? #11276

mbiggs-gresham opened this issue Oct 6, 2023 · 5 comments

Comments

@mbiggs-gresham
Copy link

mbiggs-gresham commented Oct 6, 2023

I'm using useLazyQuery and manually fetching the data using a promise. I also have my InMemoryCache configured so that as more data arrives, it merges it and it also replaces some of the child objects such as dates etc with DayJS objects instead.

The data returned to the initial fetchRows Promise includes the modified version with the changes made within the cache. The data passed to the Promise of the fetchMore however only has the last batch of rows and none of the sub objects are replaced. It only seems to give the latest set of data exactly as received via the network.

If i console log the data from the useLazyQuery hook it always includes the correctly modified changes from the cache (original batch plus new batch plus all child objects correctly swapped).

const [fetchRows, { data, fetchMore }] = useLazyQuery(QUERY);

console.log(data); // always includes full set of data with all changes from cache.

fetchRows({ variables: { id: 0, cursor: 0 }}).then(({ data }) => {
    // data includes changes from the cache.
});

fetchMore({ variables: { id: 0, cursor: 100 }}).then(({ data }) => {
    // data is the last batch of raw data only and does not include modifications from cache.
});

ps) I'm not actually calling them sequentially like this, they are being called at the appropriate times via events. I've just listed it like this for simplicity. I'm also use keyArgs: ['id'].

Why does the fetchMore not give the modified cache versions?

I'm using apollo-client v3.8.5.

@bignimbus bignimbus added the 🏓 awaiting-team-response requires input from the apollo team label Oct 18, 2023
@bignimbus
Copy link
Contributor

Hi @mbiggs-gresham 👋🏻 thanks for opening this Issue! Your configuration of InMemoryCache is a key detail here. I recommend sharing a runnable reproduction of the issue so that the community and/or maintainers have the best chance at being precise and complete with a response 🙏🏻

@bignimbus
Copy link
Contributor

As a follow-up, please note that fetchMore will update the data object. For example, this should work:

fetchMore({ variables: { id: 0, cursor: 100 }}).then(() => {
  console.log(data); // don't use the locally scoped `data` argument
});

The promise returned by fetchMore won't necessarily have run through your type policies - this is not stated outright in the docs but if you scroll down to the code blocks in this section, you'll see a sample usage of the fetchMore promise that's more idiomatic. Let us know if that helps and if not, please do provide a runnable reproduction so we can get into more detail. Thanks!

@bignimbus bignimbus added the 🏓 awaiting-contributor-response requires input from a contributor label Oct 18, 2023
@mbiggs-gresham
Copy link
Author

Hi, thanks for the response. That's exactly the problem, the local data given to the fetch promise does run through the type policies, so does refetch, but fetchMore doesn't. It seems inconsistent.

@bignimbus
Copy link
Contributor

Thanks for the feedback! We don't recommend using the resolved promise value as the source of truth in your application - all the examples in the docs show the data object as the source of truth except in very specific scenarios. Can you tell us more about your use case and why this distinction between data and the resolved promise value is an issue for your application?

@bignimbus bignimbus added 🏓 awaiting-contributor-response requires input from a contributor and removed 🏓 awaiting-contributor-response requires input from a contributor labels Oct 20, 2023
@mbiggs-gresham
Copy link
Author

mbiggs-gresham commented Oct 20, 2023

That's interesting, I didn't realise that. We were using the promises because we had some quite complex logic that could be triggered by various user interactions. We also have quite a few useCallback's which when using the global data ended up causing constant re-renders due to some of our other functions changing.

However, taking your advice, i've refactored our app to do as you say and use the global data, fixed all the issues and it seems to be working now.

I think the fetchMore local data is inconsistent still, but if it's not recommended i'm happy to no longer use it. Thanks. 👍

@github-actions github-actions bot removed the 🏓 awaiting-contributor-response requires input from a contributor label Oct 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants