103

I have a Mongoose schema with an array lists of objects that consist of a reference to another collection and a nested array of numbers:

var Schema, exports, mongoose, schema;
    
mongoose = require("mongoose");
    
Schema = mongoose.Schema;
    
schema = new Schema({
    name: {
        type: String,
        required: true,
        unique: true,
        trim: true
    },
    lists: [{
        list: {
            type: Schema.ObjectId,
            require: true,
            ref: "List"
        },
        allocations: [{
            type: Number,
            required: true
        }]
    }],
    createdAt: {
        type: Date,
        "default": Date.now
    },
    updatedAt: {
        type: Date
    }
});
    
exports = module.exports = mongoose.model("Portfolio", schema);

However, I cannot get populate to work as expected without getting a TypeError: Cannot read property 'ref' of undefined. I've tried populate('list') and populate('lists list') but I'm either not calling things correctly or my Schema isn't formed correctly. I don't have this problem if I simply reference the lists by themselves:

lists: [{
    type: Schema.ObjectId,
    require: true,
    ref: "List"
}]

but I want to have the allocations array alongside each list. What do I need to do to get the behavior I want?

7 Answers 7

171

I found the answer: populate('lists.list') works. Thanks to this question: Mongoose populate within an object?

Sign up to request clarification or add additional context in comments.

2 Comments

Hi friend this is not working for me any thing i miss. i havent use required.
it worked for me. i was populating for each service inside services array thanks. services:[{ quantity: Number, service: { type:Schema.Types.ObjectId, ref: 'vas' } }],
9

Actual answer:

Use this,

populate('lists.list')

Extra:

Here are lists are an array of objects (list). In JS you can access this like that,

console.log(lists.list);

and MongoDB syntax is 99% similar to JS syntax. so....................

1 Comment

How can I populate adminId here? adminInfo: { _id: false, adminId: [{ type: Schema.Types.ObjectId, ref: 'User' }] }
8
lists: [{
    list: {
        type: Schema.ObjectId,
        require: true,
        ref: "List"
    },
    allocations: [{
        type: Number,
        required: true
    }]
}],

=> Because it's an array of objects, you can do this -: Portfolio.populate('lists.list');

2.

lists: [{
    type: Schema.ObjectId,
    require: true,
    ref: "List"
}]

=> Because it's an array, you just have to do this -: Portfolio.populate('lists');

3 Comments

XYZ.populate('adminInfo.adminId');
Already tried that please have a look here: stackoverflow.com/questions/62531177/…
The first one worked, but the second one didn't. Any idea why?
4

if you have nested schema

YourSchema.find()
   .populate({
        path: 'map_data',
        populate: {
            path: 'location' 
        }
})

it's work for me

Comments

2
populate('lists.list')
populate(
 {
   path: "lists",
   populate : {
     path: "list",
     model: "List"
   }
 }
)

1 Comment

Please add more details explaining why your approach is working or better than previous answers.
1
// Cart schema  
var CartSchema = new mongooseSchema({
    productDetails: [{
        productId: {
            type: mongoose.Schema.ObjectId,
            required: true,
            ref: 'Product'

        },
        productCount: Number,
    }],
    UserId: {
        type: String,
        default: '',
        required: true,
        trim: true,
    },
    shopId: {
        type: String,
        default: '',
        required: true,
        trim: true,
    },
});

// add this .populate('productDetails.productId').

db.Cart.find({
    UserId: userId,
    shopId: shopId
}).populate('productDetails.productId')
.skip(pagination.skip)
.limit(pagination.limit)
.exec(function(error,

CartList) {

    if (error) {
        callback(error, null)
    } else {
        callback(null, CartList)
    }
});

Comments

1

Populate didn't work in my case when nesting to array my Schema was

const chatSchema = mongoose.Schema({
    chats: [{
        type: Schema.Types.ObjectId,
        ref: "ChatMsg" 
    }],
})

How I solved it

Chat.findOne({ 
    customer: req.body.customer, 
    agency: req.body.agency 
}, (err, chat) => {
    if (err) {
        res.status(422).send("Our fault");
    }

    chat.populate("chats").execPopulate(() => {
        res.send(chat);
    });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.