`updater` does not work correctly when using subscription in Relay Modern
I am using Relay Modern in my application and have successfully integrated subscriptions using the feature requestSubscription
. Everything works well and the function updater
I am using to update the cache is called correctly with the appropriate subscription payload.
A subscription is used to add a new item to the list of items Link
. This is what a subscription looks like:
NewLinkSubscription.js
const newLinkSubscription = graphql`
subscription NewLinkSubscription {
Link {
mutation
node {
id
description
url
createdAt
postedBy {
id
name
}
}
}
}
`
export default (updater, onError) => {
const subscriptionConfig = {
subscription: newLinkSubscription,
variables: {},
updater,
onError
}
requestSubscription(
environment,
subscriptionConfig
)
}
Then I have a component LinkList
that displays all of the items Link
. In componentDidMount
this component, I initiate NewLinkSubscription
:
LinkList.js
class LinkList extends Component {
componentDidMount() {
NewLinkSubscription(
proxyStore => {
const createLinkField = proxyStore.getRootField('Link')
const newLink = createLinkField.getLinkedRecord('node')
const viewerProxy = proxyStore.get(this.props.viewer.id)
const connection = ConnectionHandler.getConnection(viewerProxy, 'LinkList_allLinks')
if (connection) {
ConnectionHandler.insertEdgeAfter(connection, newLink)
}
},
error => console.log(`An error occured:`, error),
)
}
render() {
console.log(`LinkList - render `, this.props.viewer.allLinks.edges)
return (
<div>
{this.props.viewer.allLinks.edges.map(({node}) =>
{
console.log(`render node: `, node)
return <Link key={node.id} link={node} viewer={this.props.viewer} />
}
)}
</div>
)
}
}
export default createFragmentContainer(LinkList, graphql`
fragment LinkList_viewer on Viewer {
id
...Link_viewer
allLinks(last: 100, orderBy: createdAt_DESC) @connection(key: "LinkList_allLinks", filters: []) {
edges {
node {
...Link_link
}
}
}
}
`)
Now what happens when a subscription comes with a new one Link
. updater
is called correctly and it seems that the new node is inserted into the connection correctly (at least ConnectionHandler.insertEdgeAfter(connection, newLink)
)).
This causes the component to reload. When I debug render
for data validation ( props.viewer.allLinks.edges
), I see that a new node has been added to the connection, so the list actually contains another item now! However, the problem is that this new node is actually the undefined
one causing the application to crash!
Does anyone see what I am missing here?
source to share
I managed to get it to work, this is how I applied it updater
now:
NewLinkSubscription(
proxyStore => {
const linkField = proxyStore.getRootField('Link')
const newLink = linkField.getLinkedRecord('node')
const viewerProxy = proxyStore.get(this.props.viewer.id)
const connection = ConnectionHandler.getConnection(viewerProxy, 'LinkList_allLinks', {
last: 100,
orderBy: 'createdAt_DESC'
})
if (connection) {
const edge = ConnectionHandler.createEdge(proxyStore, connection, newLink, 'allLinks')
ConnectionHandler.insertEdgeBefore(connection, edge)
}
},
error => console.log(`An error occurred:`, error),
)
source to share