Skip to content

Commit ffc523f

Browse files
authoredMay 14, 2021
Improve support for nested keys (#1364)
* Better support for nested keys * Added a test for nested fields Bugfix on ObjectStateMutations patch * Move the new test under integration/ * Modified an existing test ParseUser.get('password') used to return undefined, now password is not an attribute * Use curly braces
1 parent 86c05ad commit ffc523f

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed
 

‎integration/test/ParseObjectTest.js

+14
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,20 @@ describe('Parse Object', () => {
401401
assert.equal(result.get('objectField').number, 20);
402402
});
403403

404+
it('can set non existing nested fields to objects', async () => {
405+
const o = new Parse.Object('Person');
406+
expect(o.attributes).toEqual({});
407+
o.set('data', {});
408+
await o.save();
409+
expect(o.get('data')).toEqual({});
410+
o.set('data.a', {});
411+
await o.save();
412+
expect(o.get('data')).toEqual({ a: {} });
413+
o.set('data.a.b', {});
414+
await o.save();
415+
expect(o.get('data')).toEqual({ a: { b: {} } });
416+
});
417+
404418
it('can set non existing fields', async () => {
405419
const obj = new TestObject();
406420
obj.set('objectField', { number: 5 });

‎integration/test/ParseUserTest.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ describe('Parse User', () => {
505505
return user.save();
506506
})
507507
.then(() => {
508-
assert.equal(Object.keys(user.attributes).length, 6);
508+
assert.equal(Object.keys(user.attributes).length, 5);
509509
assert(user.attributes.hasOwnProperty('username'));
510510
assert(user.attributes.hasOwnProperty('email'));
511511
return user.destroy();

‎src/ObjectStateMutations.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,27 @@ export function estimateAttributes(
154154
return data;
155155
}
156156

157+
function nestedSet(obj, key, value) {
158+
const path = key.split('.');
159+
for (let i = 0; i < path.length - 1; i++) {
160+
if (!(path[i] in obj)) obj[path[i]] = {};
161+
obj = obj[path[i]];
162+
}
163+
if (typeof value === 'undefined') {
164+
delete obj[path[path.length - 1]];
165+
} else {
166+
obj[path[path.length - 1]] = value;
167+
}
168+
}
169+
157170
export function commitServerChanges(
158171
serverData: AttributeMap,
159172
objectCache: ObjectCache,
160173
changes: AttributeMap
161174
) {
162175
for (const attr in changes) {
163176
const val = changes[attr];
164-
serverData[attr] = val;
177+
nestedSet(serverData, attr, val);
165178
if (
166179
val &&
167180
typeof val === 'object' &&

‎src/ParseObject.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ class ParseObject {
409409
for (attr in pending) {
410410
if (pending[attr] instanceof RelationOp) {
411411
changes[attr] = pending[attr].applyTo(undefined, this, attr);
412-
} else if (!(attr in response) && !attr.includes('.')) {
412+
} else if (!(attr in response)) {
413413
// Only SetOps and UnsetOps should not come back with results
414414
changes[attr] = pending[attr].applyTo(undefined);
415415
}

0 commit comments

Comments
 (0)
Please sign in to comment.