Reputation: 21
I'm attempting to learn Relay by implementing TodoMVC from scratch. I can query my data like this which is working well:
query {
allTodos(first: 100) {
totalCount
completedCount
edges {
node {
id
text
completed
}
}
}
}
I got the idea to add the totalCount
and completedCount
metadata to the connection from here: http://graphql.org/learn/pagination/#end-of-list-counts-and-connections
It's similar in this example: https://github.com/graphql/swapi-graphql/blob/master/src/schema/index.js#L78
Now I am writing a mutation to change the completed
field of a Todo
given its id
.
I gather I will need to return the new completedCount
in the mutation payload, but I'm not sure how to implement getConfigs()
to update this in the client-side store. I don't have an id
for the connection, right? Is there is a flaw in my schema design? Thanks!
Upvotes: 2
Views: 278
Reputation: 7966
Assuming your mutation returns a viewer
, you'll need to add the viewer
to your fatQuery
and getConfigs
. I think this tutorial might be helpful. Here's the excerpt relevant to your task:
Adding a Todo is more complex. The reason for this is that we need to update not only the state of a Todo object that we will create, but also a connection where it is stored - the count of Todos will change, as well as the listing of Todo nodes in edges.
import Relay from 'react-relay'; export default class AddTodoMutation extends Relay.Mutation { static fragments = { viewer: () => Relay.QL`fragment on ReindexViewer { id allTodos { count, } }` }; getMutation() { return Relay.QL`mutation{ createTodo }`; } getVariables() { return { text: this.props.text, complete: false, }; } getFatQuery() { return Relay.QL` fragment on _TodoPayload { changedTodoEdge, viewer { id, allTodos { count } } } `; } getConfigs() { return [{ type: 'RANGE_ADD', parentID: this.props.viewer.id, connectionName: 'allTodos', edgeName: 'changedTodoEdge', rangeBehaviors: { '': 'prepend', }, }, { type: 'FIELDS_CHANGE', fieldIDs: { viewer: this.props.viewer.id, }, }]; } getOptimisticResponse() { return { changedTodoEdge: { node: { text: this.props.text, complete: false, }, }, viewer: { id: this.props.viewer.id, allTodos: { count: this.props.viewer.allTodos.count + 1, }, }, }; } }
In order to perform this mutation, we need some data that might not be available to the component - the id of viewer object and count of allTodos connection. Therefore we need to specify fragments for the mutation same way as we specify them for containers.
Our configs are more complex this time too - we need to add our new Todo to a connection, so we use RANGE_ADD mutation config. Relay expects an edge to be passed in payload, not just a Todo, Reindex provides changedTodoEdge for this. Lastly we need to fetch updated connection count from the server and for this viewer field is available for every payload.
In our optimistic update we increment the count of allTodos, so that we change our “total” display without any delay.
Upvotes: 0