Skip to content

Commit 7d26ad2

Browse files
committed
perf: avoid double-calling setters when pushing onto an array
Fix #11380 Re: #13456
1 parent b047690 commit 7d26ad2

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

lib/types/array/methods/index.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,7 @@ const methods = {
411411
addToSet() {
412412
_checkManualPopulation(this, arguments);
413413

414-
let values = [].map.call(arguments, this._mapCast, this);
415-
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
414+
const values = [].map.call(arguments, this._mapCast, this);
416415
const added = [];
417416
let type = '';
418417
if (values[0] instanceof ArraySubdocument) {
@@ -423,7 +422,7 @@ const methods = {
423422
type = 'ObjectId';
424423
}
425424

426-
const rawValues = utils.isMongooseArray(values) ? values.__array : this;
425+
const rawValues = utils.isMongooseArray(values) ? values.__array : values;
427426
const rawArray = utils.isMongooseArray(this) ? this.__array : this;
428427

429428
rawValues.forEach(function(v) {
@@ -690,10 +689,7 @@ const methods = {
690689

691690
_checkManualPopulation(this, values);
692691

693-
const parent = this[arrayParentSymbol];
694692
values = [].map.call(values, this._mapCast, this);
695-
values = this[arraySchemaSymbol].applySetters(values, parent, undefined,
696-
undefined, { skipDocumentArrayCast: true });
697693
let ret;
698694
const atomics = this[arrayAtomicsSymbol];
699695
this._markModified();
@@ -925,7 +921,6 @@ const methods = {
925921
values = arguments;
926922
} else {
927923
values = [].map.call(arguments, this._cast, this);
928-
values = this[arraySchemaSymbol].applySetters(values, this[arrayParentSymbol]);
929924
}
930925

931926
const arr = utils.isMongooseArray(this) ? this.__array : this;

test/types.array.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,4 +1915,26 @@ describe('types array', function() {
19151915
}
19161916
});
19171917
});
1918+
1919+
it('calls array setters (gh-11380)', function() {
1920+
let called = 0;
1921+
const Test = db.model('Test', new Schema({
1922+
intArr: [{
1923+
type: Number,
1924+
set: v => {
1925+
++called;
1926+
return Math.floor(v);
1927+
}
1928+
}]
1929+
}));
1930+
1931+
assert.equal(called, 0);
1932+
const doc = new Test({ intArr: [3.14] });
1933+
assert.deepStrictEqual(doc.intArr, [3]);
1934+
assert.equal(called, 1);
1935+
1936+
doc.intArr.push(2.718);
1937+
assert.deepStrictEqual(doc.intArr, [3, 2]);
1938+
assert.equal(called, 2);
1939+
});
19181940
});

0 commit comments

Comments
 (0)