Skip to content

Commit 5e0541c

Browse files
committed
allow array getters to return non-arrays fix #38
1 parent 3d523e9 commit 5e0541c

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function applyGettersToDoc(schema, doc) {
109109
}
110110

111111
const val = schematype.applyGetters(mpath.get(path, doc), doc, true);
112-
if (val && schematype.$isMongooseArray) {
112+
if (Array.isArray(val) && schematype.$isMongooseArray) {
113113
if (schematype.$isMongooseDocumentArray) {
114114
val.forEach((subdoc) => applyGettersToDoc.call(this, schematype.schema, subdoc));
115115
} else {

test/index.test.js

+53
Original file line numberDiff line numberDiff line change
@@ -473,4 +473,57 @@ describe('mongoose-lean-getters', function() {
473473
await BaseModel.findById(entry._id).lean({ getters: true });
474474
});
475475
});
476+
477+
it('handles getters on primitive arrays', async function() {
478+
const schema = new mongoose.Schema({
479+
integers: {
480+
type: [Number],
481+
get: v => Array.isArray(v) ? v.map(i => Math.round(i)) : v
482+
}
483+
});
484+
schema.plugin(mongooseLeanGetters);
485+
486+
const Model = mongoose.model('primitiveArrayGetters', schema);
487+
488+
await Model.deleteMany({});
489+
await Model.create({ integers: [1.1, 2.2, 3.3] });
490+
491+
const doc = await Model.findOne().lean({ getters: true });
492+
493+
assert.deepStrictEqual(doc.integers, [1, 2, 3]);
494+
});
495+
496+
it('should should allow array getters to return non-arrays', async function() {
497+
const userSchema = new mongoose.Schema({
498+
emails: {
499+
type: [String],
500+
// returns undefined, string, or array
501+
get: (val) => !val || !val.length ? undefined : (val.length === 1 ? val[0] : val),
502+
set: (val) => typeof val === 'string' ? [val] : val,
503+
}
504+
});
505+
userSchema.plugin(mongooseLeanGetters);
506+
const User = mongoose.model('gh-37-transform-arrays', userSchema);
507+
508+
const variants = [
509+
{ sourceVal: 'foo', expectedVal: 'foo' },
510+
{ sourceVal: ['foo'], expectedVal: 'foo' },
511+
{ sourceVal: ['foo', 'bar'], expectedVal: ['foo', 'bar'] },
512+
{ sourceVal: [], expectedVal: undefined },
513+
{ sourceVal: null, expectedVal: undefined },
514+
{ sourceVal: undefined, expectedVal: undefined },
515+
];
516+
517+
await Promise.all(
518+
variants.map(async({ sourceVal, expectedVal }) => {
519+
const user = new User({ emails: sourceVal });
520+
await user.save();
521+
522+
const foundUser = await User.findById(user._id).lean({ getters: true });
523+
const stringified = JSON.stringify({ sourceVal, expectedVal });
524+
assert.deepStrictEqual(user.emails, expectedVal, `user did not have expected value ${stringified}`);
525+
assert.deepStrictEqual(foundUser.emails, expectedVal, `foundUser did not have expected value ${stringified}`);
526+
})
527+
);
528+
});
476529
});

0 commit comments

Comments
 (0)