From 1b190b63f6067e950a385b900e94d7ad0ec2b3d6 Mon Sep 17 00:00:00 2001 From: Jeremy Philippe Date: Sat, 16 May 2020 12:32:30 +0200 Subject: [PATCH] fix(documentarray): make sure you can call `unshift()` after `map()` Fix #9012 --- lib/types/core_array.js | 12 +++++++++--- test/types.documentarray.test.js | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/types/core_array.js b/lib/types/core_array.js index b6632359daa..c4c6b33b441 100644 --- a/lib/types/core_array.js +++ b/lib/types/core_array.js @@ -879,7 +879,7 @@ class CoreMongooseArray extends Array { * * ####Note: * - * _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._ + * _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwriting any changes that happen between when you retrieved the object and when you save it._ * * @api public * @method unshift @@ -889,8 +889,14 @@ class CoreMongooseArray extends Array { unshift() { _checkManualPopulation(this, arguments); - let values = [].map.call(arguments, this._cast, this); - values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]); + let values; + if (this[arraySchemaSymbol] == null) { + values = arguments; + } else { + values = [].map.call(arguments, this._cast, this); + values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]); + } + [].unshift.apply(this, values); this._registerAtomic('$set', this); this._markModified(); diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index 22d9db368a9..93bafeccaa8 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -611,6 +611,27 @@ describe('types.documentarray', function() { 'd' ]); }); + + it('unshift() after map() works (gh-9012)', function() { + const MyModel = db.model('Test', Schema({ + myArray: [{ name: String }] + })); + + const doc = new MyModel({ + myArray: [{ name: 'b' }, { name: 'c' }] + }); + let myArray = doc.myArray; + + myArray = myArray.map(val => ({ name: `${val.name} mapped` })); + + myArray.unshift({ name: 'a inserted' }); + + assert.deepEqual(myArray.map(v => v.name), [ + 'a inserted', + 'b mapped', + 'c mapped' + ]); + }); }); it('cleans modified subpaths on splice() (gh-7249)', function() {