Skip to content

Commit 25b6798

Browse files
committedOct 20, 2019
fix(populate): make ArraySubdocument#populated() return a value when the path is populated
Re: #8247
1 parent 8ddfc0a commit 25b6798

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed
 

‎lib/document.js

+41-2
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,7 @@ Document.prototype.$__init = function(doc, opts) {
486486

487487
// handle docs with populated paths
488488
// If doc._id is not null or undefined
489-
if (doc._id !== null && doc._id !== undefined &&
490-
opts.populated && opts.populated.length) {
489+
if (doc._id != null && opts.populated && opts.populated.length) {
491490
const id = String(doc._id);
492491
for (let i = 0; i < opts.populated.length; ++i) {
493492
const item = opts.populated[i];
@@ -501,6 +500,8 @@ Document.prototype.$__init = function(doc, opts) {
501500

502501
init(this, doc, this._doc, opts);
503502

503+
markArraySubdocsPopulated(this, opts.populated);
504+
504505
this.emit('init', this);
505506
this.constructor.emit('init', this);
506507

@@ -509,6 +510,44 @@ Document.prototype.$__init = function(doc, opts) {
509510
return this;
510511
};
511512

513+
/*!
514+
* If populating a path within a document array, make sure each
515+
* subdoc within the array knows its subpaths are populated.
516+
*
517+
* ####Example:
518+
* const doc = await Article.findOne().populate('comments.author');
519+
* doc.comments[0].populated('author'); // Should be set
520+
*/
521+
522+
function markArraySubdocsPopulated(doc, populated) {
523+
if (doc._id == null || populated == null || populated.length === 0) {
524+
return;
525+
}
526+
527+
const id = String(doc._id);
528+
for (const item of populated) {
529+
if (item.isVirtual) {
530+
continue;
531+
}
532+
const path = item.path;
533+
const pieces = path.split('.');
534+
for (let i = 0; i < pieces.length - 1; ++i) {
535+
const subpath = pieces.slice(0, i + 1).join('.');
536+
const rest = pieces.slice(i + 1).join('.');
537+
const val = doc.get(subpath);
538+
if (val == null) {
539+
continue;
540+
}
541+
if (val.isMongooseDocumentArray) {
542+
for (let j = 0; j < val.length; ++j) {
543+
val[j].populated(rest, item._docs[id][j], item);
544+
}
545+
break;
546+
}
547+
}
548+
}
549+
}
550+
512551
/*!
513552
* Init helper.
514553
*

0 commit comments

Comments
 (0)
Please sign in to comment.