Skip to content

Commit 5e86f78

Browse files
committed
Avoid exceptions when encountering unsaved objects in dirty mutable containers
1 parent cbaa41e commit 5e86f78

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/ParseObject.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,15 @@ export default class ParseObject {
225225
) {
226226
// Due to the way browsers construct maps, the key order will not change
227227
// unless the object is changed
228-
var json = encode(val, false, true);
229-
var stringified = JSON.stringify(json);
230-
if (objectCache[attr] !== stringified) {
228+
try {
229+
var json = encode(val, false, true);
230+
var stringified = JSON.stringify(json);
231+
if (objectCache[attr] !== stringified) {
232+
dirty[attr] = val;
233+
}
234+
} catch (e) {
235+
// Error occurred, possibly by a nested unsaved pointer in a mutable container
236+
// No matter how it happened, it indicates a change in the attribute
231237
dirty[attr] = val;
232238
}
233239
}

src/__tests__/ParseObject-test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,6 +1565,36 @@ describe('ObjectController', () => {
15651565
]);
15661566
xhrs[0].onreadystatechange();
15671567
}));
1568+
1569+
it('does not fail when checking if arrays of pointers are dirty', () => {
1570+
var objectController = CoreManager.getObjectController();
1571+
var xhrs = [];
1572+
for (var i = 0; i < 2; i++) {
1573+
xhrs[i] = {
1574+
setRequestHeader: jest.genMockFn(),
1575+
open: jest.genMockFn(),
1576+
send: jest.genMockFn(),
1577+
status: 200,
1578+
readyState: 4
1579+
};
1580+
}
1581+
var current = 0;
1582+
RESTController._setXHR(function() { return xhrs[current++]; });
1583+
xhrs[0].responseText = JSON.stringify([{ success: { objectId: 'i333' } }]);
1584+
xhrs[1].responseText = JSON.stringify({});
1585+
var brand = ParseObject.fromJSON({
1586+
className: 'Brand',
1587+
objectId: 'b123',
1588+
items: [{ __type: 'Pointer', objectId: 'i222', className: 'Item' }]
1589+
});
1590+
expect(brand._getSaveJSON()).toEqual({});
1591+
var items = brand.get('items');
1592+
items.push(new ParseObject('Item'));
1593+
brand.set('items', items);
1594+
expect(function() { brand.save(); }).not.toThrow();
1595+
1596+
xhrs[0].onreadystatechange();
1597+
});
15681598
});
15691599

15701600
class MyObject extends ParseObject {

0 commit comments

Comments
 (0)