diff --git a/src/ParseObject.js b/src/ParseObject.js index 2f81cff78..a252db50f 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -764,6 +764,24 @@ class ParseObject { return this.set(attr, new IncrementOp(amount)); } + /** + * Atomically decrements the value of the given attribute the next time the + * object is saved. If no amount is specified, 1 is used by default. + * + * @param attr {String} The key. + * @param amount {Number} The amount to decrement by (optional). + * @return {(ParseObject|Boolean)} + */ + decrement(attr: string, amount?: number): ParseObject | boolean { + if (typeof amount === 'undefined') { + amount = 1; + } + if (typeof amount !== 'number') { + throw new Error('Cannot decrement by a non-numeric amount.'); + } + return this.set(attr, new IncrementOp(amount * -1)); + } + /** * Atomically add an object to the end of the array associated with a given * key. diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index 77c4bd61f..cbb798d69 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -491,6 +491,50 @@ describe('ParseObject', () => { expect(o2.attributes).toEqual({ age: 41 }); }); + + it('can decrement a field', () => { + const o = new ParseObject('Person'); + o.decrement('age'); + expect(o.attributes).toEqual({ age: -1 }); + expect(o.op('age') instanceof IncrementOp).toBe(true); + expect(o.dirtyKeys()).toEqual(['age']); + expect(o._getSaveJSON()).toEqual({ + age: { __op: 'Increment', amount: -1 } + }); + + o.decrement('age', 4); + expect(o.attributes).toEqual({ age: -5 }); + expect(o._getSaveJSON()).toEqual({ + age: { __op: 'Increment', amount: -5 } + }); + + expect(o.decrement.bind(o, 'age', 'four')).toThrow( + 'Cannot decrement by a non-numeric amount.' + ); + expect(o.decrement.bind(o, 'age', null)).toThrow( + 'Cannot decrement by a non-numeric amount.' + ); + expect(o.decrement.bind(o, 'age', { amount: 4 })).toThrow( + 'Cannot decrement by a non-numeric amount.' + ); + + o.set('age', 30); + o.decrement('age'); + expect(o.attributes).toEqual({ age: 29 }); + expect(o._getSaveJSON()).toEqual({ + age: 29 + }); + + const o2 = new ParseObject('Person'); + o2._finishFetch({ + objectId: 'ABC123', + age: 40 + }); + expect(o2.attributes).toEqual({ age: 40 }); + o2.decrement('age'); + expect(o2.attributes).toEqual({ age: 39 }); + }); + it('can set nested field', () => { const o = new ParseObject('Person'); o._finishFetch({