Mongoose: Populate nested refObject in array

Created on 12 Mar 2013  路  6Comments  路  Source: Automattic/mongoose

Hi,
I'm using 3.6.x version and here is my sample schema to reproduce :

var PersonSchema = new Schema({
  name    : String,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var StorySchema = new Schema({
  creator : { type: Schema.Types.ObjectId, ref: 'Person' },
  title    : String,
});

I'm trying to populate the creator ref for each stories saved, I tried the both path :

Person.findById(user1._id).populate("stories stories.creator"}).exec(function(err, doc)
Person.findById(user1._id).populate("stories stories.$.creator"}).exec(function(err, doc)

but I got the: TypeError: Cannot call method 'path' of undefined

My tests is running here :https://runnable.com/UT9iTD2wDj1UACXx

Thank you

Most helpful comment

Mongoose now supports deep populate. Example code:

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

User.
  findOne({ name: 'Val' }).
  populate({
    path: 'friends',
    // Get friends of friends - populate the 'friends' array for every friend
    populate: { path: 'friends' }
  });

All 6 comments

Person.findById(user1._id).populate("stories")
    .exec(function(err, doc {
         Story.populate(doc.stories, {path: 'creator'}, function (err, doc) {

         })
     })

closing per posted solution. thanks @vovan22

I know this is 7 months old but I'm having the same issue. @vovan22 solution isn't even valid javascript, nor can I make out what he's trying to do.

From what I can gather he's saying this?

 User
        .find({
            club: user.club
        })
        .populate('ratings')
        .exec(function (err, users) {

            Rating.populate(users.ratings, { path: 'rater' }, function( err, doc) {
                res.json(doc);
            });
        });

Which doesn't work

I tried this but it just gives me null on the rater

    User
        .find({
            club: user.club
        })
        .populate('ratings')
        .exec(function (err, users) {

            Rating.populate(users, {
                path: 'ratings.rater'
            }, function (err, doc) {
                res.json(doc);
            });
        });

EDIT

Ok I solved it with this. Not sure if this is correct but it works.

    User
        .find({
            club: user.club
        })
        .populate('ratings')
        .exec(function (err, users) {

            var iter = function (user, callback) {
                Rating.populate(user.ratings, {
                    path: 'rater'
                }, callback);
            };

            async.each(users, iter, function done(err) {
                res.json(users);
            });
        });

For me doesn't work, I tried this:

 `async.forEach(value,function(item,callback) {

                User.populate(item, {

                        path: 'tasks.createdby tasks.assignedto tasks.contributors',

                        select: 'username mail _id'

                    },

                    function(error,output) {

                        User.populate(output.tasks, {

                                path: 'comments._user',

                                select: 'username mail _id'

                            },

                            function(error,output2) {        

                                 arrUserstories.push(output2);

                                callback();

                            });

                    });

            }, function(err) {

                return promise.done(err, arrUserstories);

            });`

But output2 seems an array with a json stringify, but if I catch the first position to do parse.JSON it me undefined.
Output2:
[{"_id":"57518fc9d5b9a7855db1d611","numTask":5,"subject":"Implementar m茅todo POST para el m贸dulo userstory en el API REST","createdby":{"_id":"56cb877e73da764818ec5ded","mail":"[email protected]","username":"1izpena"},"__v":0,"assignedto":{"_id":"56cb879e73da764818ec5def","mail":"[email protected]","username":"asier"},"attachments":[],"comments":[{"comment":"what??","_user":{"_id":"56cb877e73da764818ec5ded","mail":"[email protected]","username":"1izpena"},"_id":"5758902598685b144bd604ae","created":"2016-06-08T21:37:41.358Z"},{"comment":"what??","_user":{"_id":"56cb877e73da764818ec5ded","mail":"[email protected]","username":"1izpena"},"_id":"575890d1cb7efda84b6cfb39","created":"2016-06-08T21:40:33.398Z"},{"comment":"not working","_user":{"_id":"56cb877e73da764818ec5ded","mail":"[email protected]","username":"1izpena"},"_id":"5758ad991c645a18577281dc","created":"2016-06-08T23:43:21.517Z"},{"comment":"or yes??",....................."createdby":{"_id":"56cb877e73da764818ec5ded","mail":"[email protected]","username":"1izpena"},"__v":0,"attachments":[],"comments":[],"requirement":{"blocked":true,"iocaine":false},"status":"Ready for test","contributors":[],"datetime":"2016-06-07T03:20:17.438Z"}]

What could I do?
Thanks you very much.

Mongoose now supports deep populate. Example code:

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

User.
  findOne({ name: 'Val' }).
  populate({
    path: 'friends',
    // Get friends of friends - populate the 'friends' array for every friend
    populate: { path: 'friends' }
  });

@makrandgupta Many thanks! it helped me a lot!

Was this page helpful?
0 / 5 - 0 ratings