diff --git a/src/ParseObject.js b/src/ParseObject.js index 95973e9e2..993631cb2 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -1305,10 +1305,12 @@ export default class ParseObject { * Creates a new instance of a Parse Object from a JSON representation. * @method fromJSON * @param {Object} json The JSON map of the Object's data + * @param {boolean} override In single instance mode, all old server data + * is overwritten if this is set to true * @static * @return {Parse.Object} A Parse.Object reference */ - static fromJSON(json) { + static fromJSON(json, override) { if (!json.className) { throw new Error('Cannot create an object without a className'); } @@ -1320,6 +1322,13 @@ export default class ParseObject { otherAttributes[attr] = json[attr]; } } + if (override) { + // id needs to be set before clearServerData can work + if (otherAttributes.objectId) { + o.id = otherAttributes.objectId; + } + o._clearServerData(); + } o._finishFetch(otherAttributes); if (json.objectId) { o._setExisted(true); @@ -1587,6 +1596,7 @@ var DefaultController = { ).then((response, status, xhr) => { if (target instanceof ParseObject) { target._clearPendingOps(); + target._clearServerData(); target._finishFetch(response); } return target; diff --git a/src/ParseQuery.js b/src/ParseQuery.js index 9e31b6146..63296f239 100644 --- a/src/ParseQuery.js +++ b/src/ParseQuery.js @@ -283,7 +283,7 @@ export default class ParseQuery { if (!data.className) { data.className = override; } - return ParseObject.fromJSON(data); + return ParseObject.fromJSON(data, true); }); })._thenRunCallbacks(options); } @@ -381,7 +381,7 @@ export default class ParseQuery { if (!objects[0].className) { objects[0].className = this.className; } - return ParseObject.fromJSON(objects[0]); + return ParseObject.fromJSON(objects[0], true); })._thenRunCallbacks(options); } diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index 38be9d9dc..afcc1643b 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -152,6 +152,27 @@ describe('ParseObject', () => { expect(o.dirty()).toBe(false); }); + it('can override old data when inflating from the server', () => { + var o = ParseObject.fromJSON({ + className: 'Item', + objectId: 'I01', + size: 'small' + }); + expect(o.get('size')).toBe('small'); + var o2 = ParseObject.fromJSON({ + className: 'Item', + objectId: 'I01', + disabled: true + }, true); + expect(o.get('disabled')).toBe(true); + expect(o.get('size')).toBe(undefined); + expect(o.has('size')).toBe(false); + + expect(o2.get('disabled')).toBe(true); + expect(o2.get('size')).toBe(undefined); + expect(o2.has('size')).toBe(false); + }); + it('is given a local Id once dirtied', () => { var o = new ParseObject('Item'); o.set('size', 'small'); @@ -1214,6 +1235,32 @@ describe('ParseObject', () => { }); })); + it('replaces old data when fetch() is called', asyncHelper((done) => { + CoreManager.getRESTController()._setXHR( + mockXHR([{ + status: 200, + response: { + count: 10 + } + }]) + ); + + var p = ParseObject.fromJSON({ + className: 'Person', + objectId: 'P200', + name: 'Fred', + count: 0 + }); + expect(p.get('name')).toBe('Fred'); + expect(p.get('count')).toBe(0); + p.fetch().then(() => { + expect(p.get('count')).toBe(10); + expect(p.get('name')).toBe(undefined); + expect(p.has('name')).toBe(false); + done(); + }); + })); + it('can destroy an object', asyncHelper((done) => { var xhr = { setRequestHeader: jest.genMockFn(),