I have a query that looks something like this:
query getGraph {
nodes {
...NodeContent
}
}
${nodeFragment}
where nodeFragment is:
fragment NodeContent on Node {
id
type
x
y
... on TriggerNode {
properties {
trigger
}
}
... on ReplyNode {
properties {
reply
keep
}
}
}
This runs fine, and I get back the desired result.
I then want to perform a mutation that adds a node, and therefore runs updateQueries. So I wrote a query like this:
mutation createNode ($type:String!, $x:Int!, $y:Int!, $properties:PropertiesInput!) {
createNode(type:$type, x:$x, y:$y, properties:$properties) {
...NodeContent
}
}
${nodeFragment}
And called it like this:
const withCreateNodeMutation = graphql(createNodeMutation, {
props: ({ mutate }) => ({
createNode: variables => mutate({
variables,
updateQueries: {
getGraph: () => { console.log('hello world'); },
},
}),
}),
});
Intended outcome:
I expected the client to at least run the updateQueries function and print hello world in the console.
Actual outcome:
Nothing happens!
Interestingly, I am getting back the correct, complete result in the APOLLO_MUTATION_RESULT action (with the correct __typenames on the fragments and everything). The updateQueries function is just not called.
This also makes optimistic UI impossible.
Could be related to #1363, #1379?
Would appreciate any thoughts or workarounds - perhaps the new imperative API? Thanks!
@benhjames I think this is related to the issues you mentioned and also to #1337. Because of its heuristic fragment matching, Apollo Client doesn't know for sure whether the response is complete and seems to think that it's in fact incomplete. This in turn leads to not running the updateQueries function. We're working on a non-heuristic fragment matcher that will not have this issue, and I'm hoping to finish and release it by next week.
I don't think there are currently any workarounds, other than downgrading to rc.0.
@helfer, no worries - can make do with refetchQueries for now. Thanks for the speedy response and glad to hear it's being looked at!
This should be fixed by https://github.com/apollographql/apollo-client/pull/1527
@Mike-Dax I upgraded to [email protected] (and therefore [email protected]), and also passed my schema into fragmentMatcher on the apollo client options but it seems to have made no difference.
updateQueries is still never called (no console.log). I traced this through Chrome's debugger: it seems that context.hasMissingField is being set to true during diffQueryAgainstStore, causing it to short circuit out of updateQueries. I'm afraid I don't know enough about that code to be able to help on that front further!
If I use update, I can update the store fine (looking at the next state via the APOLLO_MUTATION_RESULT reducer shows the correct updated store), but it won't update the props passed down into my component that uses the updated query.
The only reliable option still seems to be refetchQueries.
@benhjames could you provide a replication of the issue using https://github.com/apollographql/react-apollo-error-template? I would take a look at it.
@msimulcik sure, bit of a hectic week so hope you don't mind waiting a little bit - cheers!
@msimulcik Sorry for the delay: I've produced a minimal example repo here: https://github.com/benhjames/apollo-fragment-issue
The most important thing about this is that if you remove the ... on ReplyNode and ... on TriggerNode fragments from the query/mutation, it works just fine. As soon as you add in the fragments, the client stops calling updateQueries etc.
Interestingly, somewhere between [email protected] and [email protected], refetchQueries also stopped working.
Do let me know if there's anything else you need info-wise. Cheers :)
@helfer I think I found the culprit for this: https://github.com/apollographql/apollo-client/blob/master/src/data/fragmentMatcher.ts#L146
Currently (and as noted in the comment there), the HeuristicFragmentMatcher will positively match a TriggerNode fragment with a ReplyNode fragment despite referencing different (interface) types. Ultimately that results in hasMissingField being set to true, and the updateQueries stuff not firing.
If I change the bottom return true to return false, it works as expected i.e. doesn't match a fragment on TriggerNode as a fragment on ReplyNode. But again as the comment specifies there, I'm sure it's more complicated than that.
Was wondering what your thoughts were on this. :)
I must have done something incorrect when I previously tried using IntrospectionFragmentMatcher - I've now followed the steps outlined in #1555 and it works just fine!
Most helpful comment
@Mike-Dax I upgraded to
[email protected](and therefore[email protected]), and also passed my schema intofragmentMatcheron the apollo client options but it seems to have made no difference.updateQueriesis still never called (noconsole.log). I traced this through Chrome's debugger: it seems thatcontext.hasMissingFieldis being set totrueduringdiffQueryAgainstStore, causing it to short circuit out ofupdateQueries. I'm afraid I don't know enough about that code to be able to help on that front further!If I use
update, I can update the store fine (looking at thenext statevia theAPOLLO_MUTATION_RESULTreducer shows the correct updated store), but it won't update the props passed down into my component that uses the updated query.The only reliable option still seems to be
refetchQueries.