relay: optimisticUpdater infinite loop
In the code below, the optimisticUpdater ends up in an infinite loop. It only occurs when I set a nested record on a newly created record, and set the linked record on a parent. eg.
1. const newNode = store.create(id, type)
2. newNode.getOrCreateLinkedRecord(key)
3. parent.setLinkedRecords([...oldNodes, newNode])
Why does it end up in a loop? How can I prevent it?
Resolves values and sets them on given record
function setValues(node, input) {
Object.keys(input).forEach(key => {
const value = input[key];
if (Array.isArray(value)) node.setLinkedRecords(value, key);
else if (isPlainObject(value)) {
Object.keys(value).forEach(nestedKey => {
const nestedNode = node.getOrCreateLinkedRecord(key);
setValues(nestedNode, { [nestedKey]: value[nestedKey] });
});
} else node.setValue(value, key);
});
}
Create handler
handleCreate = () => {
const recordUpdater = ({ store, node }) => {
const parent = store.get(this.props.customer.id);
const nodes = (parent.getLinkedRecords("customerAddresses") || []).concat(node);
parent.setLinkedRecords(nodes, "customerAddresses");
};
const config = {
optimisticUpdater: store => {
const id = `client:newCustomerAddress:${tempId++}`;
const node = store.create(id, "CustomerAddress");
node.setValue(id, "id");
setValues(node, input);
recordUpdater({ store, node });
}
};
const input = {
addressType: "Private",
customerId: this.props.customer.id,
address: {
roadName: ""
}
};
commitMutation(this.props.environment, {
...config,
mutation,
variables: { input },
onCompleted: (resp, errors) => {
if (errors) reject(errors);
else resolve(resp);
},
reject
})
};
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 18 (10 by maintainers)
As @sibelius noted,
setValues()
is the problem.setLinkedRecords
accepts array of record proxies, andsetLinkedRecord
accepts a single record proxy. It’s possible to write something like yoursetValues()
function that works, but it would have to distinguish the types of objects (e.g array of scalars vs array of objects) and convert all nested objects into record proxies with e.g.store.create
or similar.