-
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
Fetch more with merge policy existing data comes undefined or previous incoming data with duplicates. #6729
Comments
You're very close to the solution, but there's one more piece that's worth understanding. The cache can't make any assumptions about the meaning of your field arguments ( While this is reasonable default strategy (in the absence of better information), it's often not a very good strategy, especially since Since you probably want there to be only one array, regardless of the arguments, the most appropriate setting is One additional subtlety: when you define both a For comparison, our export function concatPagination<T = Reference>(
keyArgs: KeyArgs = false,
): FieldPolicy<T[]> {
return {
keyArgs,
merge(existing, incoming) {
return existing ? [
...existing,
...incoming,
] : incoming;
},
};
} If you wanted to use this helper, your code could look like this: import { concatPagination } from "@apollo/client/utilities"
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
filterId: {
read() {
return filterIdVar();
}
},
people: concatPagination(),
}
}
}
}) However, even with a helper function available, I think it's useful to understand what's going on behind the scenes. As a final note, it may be tempting to define a I know that's a whole lot of information, but thanks for reading, and thanks for providing a reproduction that made it easy to see exactly what was going on! |
Perfect explanation, thank you! For the future comers, I recommend this video which helped me to digest the explanation and give more insight about ApolloClient v3. |
@benjamn In your explanation above you mention usage of |
@joebernard Yes, that was a typo. In this case, I should have only been talking about |
This thread has solved a lot of problems for me, but one is still left open. What if we have 2 different queries that call on the same field (ex: All Users and Only Known Users) where one field calls a fetchMore (All Users) and the other doesn't (Known Users, this just calls users with a different sort). In my case, using KayArgs=false makes it so that it returns the All Users query correctly (with a fetchMore) but it gets called for every query that uses the field users. So whenever I want to view Known Users it brings back the query All Users instead. Removing KeyArgs should fix the problem, both queries show up, except the fetchMore doesn't concatenate a list because my merge function's existing variable returns as undefined (just like in this thread). What can I do to be able to call 2 separate queries as well as a fetchMore for only one of them? Edit: I was able to fix this problem by making the non-fetchMore query's fetchPolicy="no-cache". But still, is there a way to fix the problem and cache it as well? |
@TanBeige I have the same problem. Same query called with and without fetchmore |
For those who will pass by this issue, even after defining the My graphQL request was like query ReservationsList($id: Int!, $offset: Int = 0) {
user(id: $id) {
name
reservations(
where: {
#...
},
order_by: {time: asc},
limit: 30,
offset: $offset
) {
id
time
numberOfPlaces
}
}
} It's tricky because here my mistake was that the The solution was quite simple to set (still hard to identify): query ReservationsList($id: Int!, $offset: Int = 0) {
user(id: $id) {
id # <- set the id to help Apollo identify the parent object of the list
name
reservations(
#...
) {
#...
}
}
} |
After "debugging" my code for the last 2 hours, and read the very well written docs this way, installed the |
Intended outcome:
I'm not sure that I totally understood the merge vs updateQuery but here is the case:
When I use merge field policy and fetch more in the same time, I expected to see that data populates with new ones.
Actual outcome:
I have the people array as I do the first request via useQuery and the data populates with the expected data. However when I do fetchMore, here is what happens:
I do fetch more, new data comes as incoming, however my existing data is undefined which is I think odd because I already have the data and showing in the UI. As you can see:
If I do fetchMore one more time, this time the existing will be filled with the previous incoming data but not the one that is already showing. And it will concatenate the prev with the incoming and the duplicate data will populate forever. But there will be no change in the UI at all.
![image](https://user-images.githubusercontent.com/26188297/88803282-e8e71c00-d1b4-11ea-9ea7-111990e66ec9.png)
When I provide read field policy it will fetchMore as expected and I can see existing data in merge but then when the filterType changes, I can't even get the new data and only read is triggered with the existing data. By using updateQuery inside fetchMore I don't see any of the issues and it works as expected.
How to reproduce the issue:
Reporduce repo:
https://github.com/ErkinKurt/react-apollo-error-template
You can change status type and it will change the data that's shown but when you press load more you will get nothing. As I tried to explain above, you can uncomment read field policy and see what happens. Thanks for your hard work.
Versions
The text was updated successfully, but these errors were encountered: