From b63255262cfc911979139103757ce4d578201488 Mon Sep 17 00:00:00 2001 From: Nathan Knight Date: Tue, 19 Mar 2024 09:31:46 -0400 Subject: [PATCH] Fixed handling discriminators in nested document arrays --- index.js | 8 +++++++- test/index.test.js | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index eaf2abb..e7df627 100644 --- a/index.js +++ b/index.js @@ -74,7 +74,7 @@ function getSchemaForDoc(schema, res) { const discriminatorValue = res[schema.discriminatorMapping.key]; let childSchema = undefined; for (const name of Object.keys(schema.discriminators)) { - const matchValue = schema.discriminators[name].discriminatorMapping.value || modelName; + const matchValue = schema.discriminators[name].discriminatorMapping.value; if (matchValue === discriminatorValue) { childSchema = schema.discriminators[name]; break; @@ -91,7 +91,13 @@ function applyGettersToDoc(schema, doc, fields, prefix) { if (Array.isArray(doc)) { for (let i = 0; i < doc.length; ++i) { const currentDoc = doc[i]; + // If the current doc is null/undefined, there's nothing to do if (currentDoc == null) continue; + // If it is a nested array, apply getters to each subdocument (otherwise it would attempt to apply getters to the array itself) + if (Array.isArray(currentDoc)) { + applyGettersToDoc.call(this, schema, currentDoc, fields, prefix); + continue; + } const schemaForDoc = getSchemaForDoc(schema, currentDoc); applyGettersToDoc.call(this, schemaForDoc, currentDoc, fields, prefix); } diff --git a/test/index.test.js b/test/index.test.js index d163e46..bcf3f5a 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -249,7 +249,7 @@ describe('mongoose-lean-getters', function() { assert.equal(docs[0].url, 'https://www.test.com discriminator field'); }); - + it('should call getters on schemas with discriminator using explicit value', async function() { const options = { discriminatorKey: 'kind' }; @@ -304,7 +304,41 @@ describe('mongoose-lean-getters', function() { assert.equal(docs[0].events[0].url, 'https://www.test.com discriminator field'); }); - + + it('should work on schemas with discriminators in nested arrays', async function() { + const options = { discriminatorKey: 'kind' }; + + const eventSchema = new mongoose.Schema({ time: Date }, options); + const clickedLinkSchema = new mongoose.Schema({ + url: { type: String, get: v => v + ' discriminator field' } + }); + eventSchema.discriminator('VisitedPage', clickedLinkSchema); + + const eventGroupSchema = new mongoose.Schema({ + events: [eventSchema] + }); + + const eventListSchema = new mongoose.Schema({ + eventGroups: [eventGroupSchema], + }); + eventListSchema.plugin(mongooseLeanGetters); + const EventGroupList = mongoose.model('EventGroupList', eventListSchema); + + await EventGroupList.deleteMany({}); + await EventGroupList.create({ + eventGroups: [{ + events: [{ + kind: 'VisitedPage', + url: 'https://www.test.com' + }], + }], + }); + + const docs = await EventGroupList.find().lean({ getters: true }); + + assert.equal(docs[0].eventGroups[0].events[0].url, 'https://www.test.com discriminator field'); + }); + it('should call getters on arrays (gh-30)', async function() { function upper(value) { return value.toUpperCase();