Open kkitay opened 4 years ago
@alessbell, I agree with @chrisregner and @RemyMachado . can you confirm if we are on the right track?
I'd say @chrisregner is on the right track:
A component will update if a selected field has been updated in the cache.
That means a few prerequisites:
__typename
and id
are the same (or you configured the cache accordingly to use different fields)users
, users(first: 50)
and users(first: 51)
are completely different fields from the cache's perspectiveI am seeing the same issue as @RemyMachado reported in the version 3.8.9
however, it seemed fixed in the version 3.7.17
.
In my case I have a list that allow users to perform an update in an entity that is loaded via a network request. I am using the cache-first
as the fetch policy. Whenever the user tries to update the entity of a record, they can also add a new record to it. This new record shows up in the other instances of this list only if I refresh the table.
It is noticeable the cache is updated, but it is not triggering to update the react components.
I can confirm that in 3.9.4
when I update the cache by providing correct id
and __typename
the component receives stale data while I can clearly see that the cache has the fresh one.
I'm sorry, but without a reproduction, we really cannot do a lot about this. We can't reproduce this on our end, so we really rely on someone providing us with a minimal reproduction of the issue.
Apologies I don't have a reproduced repo and I'm not sure if/when I can find the time for it, but I had a similar issue - I'm trying to update the user's account, and without optimistic response, the UI re-renders correctly. The payload is something like:
mutation UpdateUserMutation($settings: JSON!) {
updateAccount(input: { settings: $settings }) {
id
settings
}
}
When I try and use optimistic response, the component just re-renders with the stale data, but I can see the API response contains the new data, and the apollo chrome extension shows the correct data in the cache too.
What fixes it for me was to mutate some other piece of data as part of the mutation e.g. currency_code
mutation UpdateUserMutation($settings: JSON!, $currency_code: String) {
updateAccount(input: { currency_code: $code, settings: $settings }) {
id
currency_code
settings
}
}
Now optimistic response of:
optimisticResponse: {
updateAccount: {
id: account.id,
currency_code: newCurrencyCode,
settings: newSettings,
__typename: 'Account',
},
},
Will update the UI correctly. So my theory is that the equality check is failing when objects are involved / a new object isn't being created correctly when an object in the cache is updated?
I guess it's worth noting in my case, settings doesn't have a typename, it's just a freeform json field, so the cache doesn't have any refs/__typename to work with.
I know it isn't a solution (it's not always possible to update other data too) but hopefully the above is of some help to someone!
Edit
In my particular case, I found there's an updated_at
field in the data that auto updates with a new DateTime, so I don't have to actually mutate anything, just make sure updated_at
is being used in the query and mutation.
I've managed to reproduce this issue in a standalone repo:
https://github.com/jnsandrew/apollo-cache-error
In my case - I see the issue on storybook + mock service workers. Hope this helps to debug the issue. I'm not 100% sure if it's even an apollo thing yet, but it looks like that at the moment.
@jnsandrew I've taken a look, and in your case you provoke an error by returning an incomplete response in your msw
handler - a spec-compliant GraphQL server would never do that.
If you fix that response, it starts working as intended.
export const CompleteTask = {
args: {},
name: 'Complete task',
parameters: {
msw: {
handlers: [
graphql.query('TaskEntityListQuery', (req, res, ctx) =>
res(
ctx.data({
taskEntityList: [
{
avatar: null,
id: 2001,
completed: false,
created_at: '2023-11-27T09:45:00.274Z',
+ entity_type_id: 1,
__typename: 'Task',
},
],
}),
),
),
Doh! Thank you!
As a side note did you do anything special to get that error to show? As it doesn't come up in my console 🤔
If you are not running the production bundle you should be seeing those error messages.
I know of one third-party "Apollo Client debugger" browser extension that enforces production mode (the official one doesn't do that!), so you might want to check your browser extensions.
Intended outcome:
useQuery
(Component A).useMutation
to create Object B. In the payload, I am returning Object A, this time with a non-null Object B.Actual outcome:
Some screenshots w/ info redacted. Object A is
listing
and Object B (the object being created) islatestValidPropertyInspection
. The initial query:The mutation running and returning the new objects w/ non-null
latestValidPropertyInspection
:apollo chrome extension showing the cache updated after the mutation ran:
query:
mutation:
How to reproduce the issue: Query for a single object in one component, with a field being another object but that is returning null. In another component, mutate to create said object, but return the parent (the original single object). You should find that the component did not render.
Versions