-
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
previousResult is undefined when using updateQuery in fetchMore #5897
Comments
Can you put together a reproduction? https://github.com/apollographql/react-apollo-error-template That documentation will be rewritten before AC3 is shipped, but one thing I can tell you is that the |
I am also encountering this issue, but I am seeing it whenever I'm using the fetchMore API. I need to do some investigating, but it seems like everything is honky-dorey whenever I run this on Chrome. However, if I run this in Cordova on Android, there's going to be a CORS preflight step and the fetchMore API always comes back with a first parameter of undefined in that environment. I will investigate further, but this is certainly an issue for my team as we're coming online in AC3. |
Okay, as I investigate the difference between my two platforms (Chrome web vs Cordova Android), I'm seeing one primary difference. This line: https://github.com/apollographql/apollo-client/blob/master/src/core/ObservableQuery.ts#L596 When I log result here on web, stale is false. ...interesting EDIT: Going a little further here, I'm seeing all data returned, but the complete flag is false on Cordova and true on web. This trips isMissing = true, which bubbles up to stale = true, which ends with us at undefined I think. Will post more findings as I see why complete = false. |
Just to note, I tried the fix from #5938 to no avail unfortunately. |
Investigating further, I think its because I have two mutations running quite sequentially here. I'm sorry to be vague. If I find a fix or a source, I'll report here. |
Okay, I am through my issue here.
And then I had two concurrent mutations, one of which writes to subfield1 and one of which writes to subfield2. However, they changed the default cache normalization for objects without ids to just fully overwrite instead of a full merge function like lodash. Good for performance, bad for stability. My fix came down to making this change to my InMemoryCache:
This can be further read about here: https://github.com/apollographql/apollo-client/blob/70247206dfa59d16251ce8cae654731c0986b9fe/docs/source/caching/cache-field-behavior.md There is some new stuff full of gotchas. @benjamn - I am not sure how, but I would recommend surfacing some of the invariants that get caught here somehow as well. I don't have returnPartialData defined anywhere in my codebase, but this throw never got back to me or was never invoked. I couldn't tell: https://github.com/apollographql/apollo-client/blob/master/src/cache/inmemory/readFromStore.ts#L172 I only found this because calls to fetchMore later would have a clientData of null. |
@benjamn - I don't mean to spam you guys too much, but if you add a logger right here letting people know the mine cart just left the tracks a bit, you may have a lot less vagueness and confusion in which issues get reported:
Generally, any time I am having issues on 3.x, my first step is to add a logger to this, and then I know which fires to fight before I get to undefined client data on an updateQuery call. I'm not trying to spend too much of your time. I just wanted to recommend this logger to help keep others from being confused with your time. |
Hhaving a similar issue, no easy fix in sight tho. @toddtarsi my previous result seems to come undefined only for subscriptions |
@Thomazella - Did you add a console logger in the area I recommended above? It sucks to add a logger there, but it helped me track down some issues that weren't escaping in an obvious way. If using npm to install it, you'll have to add it to the transpiled code, but it isn't so bad. Also, feel free to ignore this if not using the InMemoryCache. |
Just a heads up, |
Yeah, I have a question: I have a query shaped something like this (pseudocode):
And I have a number of fetchMore queries, which all return |
@toddtarsi Something like this? new InMemoryCache({
typePolicies: {
User: {
fields: {
topItems: {
merge(existing = [], incoming) {
return [...existing, ...incoming];
},
},
},
},
Account: {
fields: {
accountItems: {
merge(existing = [], incoming) {
return [...existing, ...incoming];
},
},
},
},
},
}) Of course you can make this a little less repetitive by using a helper function, like the import { concatPagination } from "@apollo/client/utilities"
new InMemoryCache({
typePolicies: {
User: {
fields: {
topItems: concatPagination(),
},
},
Account: {
fields: {
accountItems: concatPagination(),
},
},
},
}) If you need to do something more complicated, |
@benjamn - Sorry, I didn't explain quite well enough. Let me try harder. This is a simplification of my schema.
The schema here is type Schema. Type User is meant to be the shape of the main user query. Now, in my app I call fetchMore with fetchSomeTopItems at some point, and fetchMore with fetchSomeAccountItems at other times. With updateQuery I would append to topItems, or accountItems as needed using some factory reducer. With cache policies, I don't see how I could do this. Ah, I see your update. Okay, so I should just use the promise result from fetchMore and use the updateQuery API manually. That makes sense, thank you for your answer. Just to check, updateQuery as a property on the fetchMore API is deprecated, but updateQuery as a direct API call is still a valid property on a query result, correct? |
Correct! |
@benjamn - Makes sense; a little bit of hoisting and I should be right as rain then. Thank you for the help sir! |
const { data, fetchMore } = useQuery(SOME_QUERY); instead of this fetchMore({
variables: { ... },
updateQuery: (prev: any, { fetchMoreResult }) => {
if (!fetchMoreResult) return prev;
return {
fetchedData: {
...prev?.fetchedData,
data: [...prev?.fetchedData?.data, ...fetchMoreResult?.fetchedData?.data],
},
};
},
}); I do something like that, and it's solve the pb fetchMore({
variables: { ... },
updateQuery: (prev: any, { fetchMoreResult }) => {
if (!fetchMoreResult) return prev;
return {
fetchedData: {
...data?.fetchedData,
data: [...data?.fetchedData?.data, ...fetchMoreResult?.fetchedData.?data],
},
};
},
}); |
I'm experiencing the same issue in @apollo/[email protected] when using useQuery. @soltysaleksandr workaround works but it would be nice if it would work out of the box |
Intended outcome:
The
previousResult
variable should contain the previous data.Actual outcome:
The
previousResult
is undefinedHow to reproduce the issue:
I followed the tutorial on this page using the Relay-style cursor pagination. After switching everything to the latest stable apollo version the
previousResult
variable contains the data.Versions
v3.0.0-beta.20
The text was updated successfully, but these errors were encountered: