Skip to content

Commit

Permalink
fix: Multiple object updates of nested keys overwrite each other (#1451)
Browse files Browse the repository at this point in the history
  • Loading branch information
mstniy committed May 1, 2024
1 parent 8f30edf commit fa4341a
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/ObjectStateMutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,14 @@ export function estimateAttributes(
if (attr.includes('.')) {
// convert a.b.c into { a: { b: { c: value } } }
const fields = attr.split('.');
const first = fields[0];
const last = fields[fields.length - 1];
data[first] = { ...serverData[first] };
let object = { ...data };
let object = data;
for (let i = 0; i < fields.length - 1; i++) {
const key = fields[i];
if (!(key in object)) {
object[key] = {};
} else {
object[key] = { ...object[key] };
}
object = object[key];
}
Expand Down
63 changes: 63 additions & 0 deletions src/__tests__/ParseObject-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,69 @@ describe('ParseObject', () => {
});
});

it('can set multiple nested fields (regression test for #1450)', () => {
const o = new ParseObject('Person');
o._finishFetch({
objectId: 'setNested2_1450',
objectField: {
number: 5,
letter: 'a',
nested: {
number: 0,
letter: 'b',
},
},
});

expect(o.attributes).toEqual({
objectField: { number: 5, letter: 'a', nested: { number: 0, letter: 'b' } },
});
o.set('objectField.number', 20);
o.set('objectField.letter', 'b');
o.set('objectField.nested.number', 1);
o.set('objectField.nested.letter', 'c');

expect(o.attributes).toEqual({
objectField: { number: 20, letter: 'b', nested: { number: 1, letter: 'c' } },
});
expect(o.op('objectField.number') instanceof SetOp).toBe(true);
expect(o.dirtyKeys()).toEqual([
'objectField.number',
'objectField.letter',
'objectField.nested.number',
'objectField.nested.letter',
'objectField',
]);
expect(o._getSaveJSON()).toEqual({
'objectField.number': 20,
'objectField.letter': 'b',
'objectField.nested.number': 1,
'objectField.nested.letter': 'c',
});

o.revert('objectField.nested.number');
o.revert('objectField.nested.letter');
expect(o._getSaveJSON()).toEqual({
'objectField.number': 20,
'objectField.letter': 'b',
});
expect(o.attributes).toEqual({
objectField: { number: 20, letter: 'b', nested: { number: 0, letter: 'b' } },
});

// Also test setting new root fields using the dot notation
o.set('objectField2.number', 0);
expect(o._getSaveJSON()).toEqual({
'objectField.number': 20,
'objectField.letter': 'b',
'objectField2.number': 0,
});
expect(o.attributes).toEqual({
objectField: { number: 20, letter: 'b', nested: { number: 0, letter: 'b' } },
objectField2: { number: 0 },
});
});

it('can increment a nested field', () => {
const o = new ParseObject('Person');
o._finishFetch({
Expand Down

0 comments on commit fa4341a

Please sign in to comment.