Reputation: 11
I am trying to make an example chat with relay and subscriptions. I've managed to make it work in some fashion. The problem is that older messages are pushed from the view when new message is added by either mutation or subscription. But it is not an actual behavior we expect from chat. We want to all loaded messages from history stay in list when new message is added to the bottom.
playground example(without subscription, but mutation is enough)
We can increment $last from container but there is no way I know of to increment it on addition of new connection node in store.
Some workarounds we've thought of with my colleague:
Try to increment $last in componentWillReceiveProps. This seems very hacky solution, because:
Do not use $last variable. Instead fetch msgs(last: 100000000) and make server return default count on first response (2 in out example) if last is big enough. In this case all will work as expected. But backend will actually fail to comply to relay-graphql connection spec.
Split MsgsContainer viewer fragment to 2 (or more) fragments:
The problem here is message with $lastMsgCursor will be excluded from both history and newMessages fragments, so may be we need third fragment: lastMessage. But then, how to query it?
None of this ideas seem to be a good way to go. So I wonder, what will be proper way to make history like pagination work?
Upvotes: 1
Views: 713
Reputation: 4228
A common pattern is to ‘make room’ for the new item, perform the mutation, and rollback the room in case the mutation fails:
addMsg() {
// Make room for the new item.
this.props.relay.setVariables({
last: this.props.relay.variables.last + 1,
});
// Perform the mutation.
this.props.relay.commitUpdate(
new AddMsgMutation({
text: "new msg",
viewer: this.props.viewer,
}),
{
onFailure: () => {
// Roll back the room if the mutation fails.
this.props.relay.setVariables({
last: this.props.relay.variables.last - 1,
});
},
},
);
}
Updated Playground: (link)
Upvotes: 0