My following query
query getMyAccount {
myAccount {
...Account
}
}
Might return null
. Since I use the default cache-first
fetch policy, it will keep returning null
even if it has been updated elsewhere.
My following query
query getMyAccount {
myAccount {
...Account
}
}
Might return null
. Since I use the default cache-first
fetch policy, it will keep returning null
even if it has been updated elsewhere.
Hey @yuki
Just to clarify, are you saying that when myAccount
is null
, then something else writes a non-null value to the cache, your query is not updating with the new value? It should definitely update with the new value. Would you be able to provide some more code on your queries? It’s difficult to tell from the query alone what might be happening.
Sorry for the late reply, I wrote some test code to explain what I encountered:
GraphQL server side:
extend type Query {
book(bookId: String!): Book
}
extend type Mutation {
updateBook(bookId: String!, name: String!): Book!
}
type Book {
_id: String!
name: String!
}
GraphQL client side:
query getBook($bookId: String!) {
book(bookId: $bookId) {
_id
name
}
}
mutation updateBook($bookId: String!, $name: String!) {
updateBook(bookId: $bookId, name: $name) {
_id
name
}
}
client-side code (Note: I wrap around @apollo/client/core myself)
ngOnInit(): void {
this.courseApi.getBookWatchQuery({ bookId: 'test' }).valueChanges.subscribe();
setTimeout(() => {
this.courseApi.updateBook({ bookId: 'test', name: 'Hello World!' });
}, 3e3);
}
Apollo Chrome extension capture (New users can’t post picture…):
It seems the whole query is used as the cache ID even if the returned value is null, so that watch query didn’t emit new value.
I want to do two things in different use cases:
book({"bookId":"test"}):null
reference Book:test
even if it’s value is null.@yuki so the problem you’re experiencing is that Apollo Client doesn’t know your schema, so its unaware that the book(bookId: ID!)
field returns a Book
type and that its value should be associated to the book you updated from your mutation. Since its null
at first, it has no way to know these two objects should be related. You need to give it a little help to understand that the book you updated in the mutation should now be the book associated to that book
field in the query.
I’m not super familiar with the Angular semantics, but the core mutate
function gives you access to an update
callback. Use this to update your cache after the mutation so that you can associate the two. It should look something like the following:
apolloClient.mutate({
mutation: gql`...`,
update(cache, { data }) {
// If we didn't get a book back, don't do anything
if (!data.updateBook) {
return
}
cache.writeQuery({
query: gql`
query ($bookId: ID!) {
book(bookId: $bookId) {
_id
name
}
}
`,
variables: { bookId: data.updateBook._id },
data: data.updateBook,
});
},
});
Let me know if that helps!
@jerelmiller Thank you! But it works partically.
Let’s say I have following GrahQL schema:
query getBook($_id: String!) {
book(_id: $_id) {
_id
name
}
}
mutation updateBook($_id: String!, $name: String!) {
updateBook(_id: $_id, name: $name) {
_id
name
}
}
query getBooks {
books {
_id
name
}
}
Now, not only updateBook
but also getBooks
can update getBook
. What if I came up more and more operations which can update getBook
.
Is there a way to make an association on getBook
side? I mean I want to associate book({"_id":"test"})
with Book:test
even if it got null
, so that later mutations
or querys
can always update it automatically.
Ah thats a great question! You can use something we like to call cache redirects which are essentially just read functions that give a hint to the cache where something should be looked up. Try defining one of those to see if that helps here!
Query: {
fields: {
book: {
read: (_, { args, toReference }) => {
// note the `args` key will match the argument name in the schema,
// not the variable name
return toReference({ __typename: "Book", _id: args._id })
}
}
}
}
Let me know if this works for you!
@jerelmiller This works! But I found a bug in Apollo Chrome extension:
The value in code gets updated, but the value in the extension not.
@yuki I think thats a bug in the chrome extension. I just started noticing this as well. I opened an issue to take a look at this over in that repo: https://github.com/apollographql/apollo-client-devtools/issues/1522.
For now, if you close and reopen devtools, it should update properly. Sorry for the bug!