98

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?

Mr.Singh
  • 1,421
  • 6
  • 21
  • 46
neverfox
  • 6,680
  • 7
  • 31
  • 40

7 Answers7

167

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

Community
  • 1
  • 1
neverfox
  • 6,680
  • 7
  • 31
  • 40
  • 2
    Hi friend this is not working for me any thing i miss. i havent use required. – Yogesh Patel Dec 14 '16 at 09:08
  • 1
    it worked for me. i was populating for each service inside services array thanks. `services:[{ quantity: Number, service: { type:Schema.Types.ObjectId, ref: 'vas' } }],` – subhashish negi May 30 '19 at 08:15
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....................

Rohit Nishad
  • 2,570
  • 2
  • 22
  • 32
  • How can I populate adminId here? `adminInfo: { _id: false, adminId: [{ type: Schema.Types.ObjectId, ref: 'User' }] }` – Rupesh Jun 23 '20 at 08:38
7
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');

Mr.Singh
  • 1,421
  • 6
  • 21
  • 46
Sonu Bhatt
  • 101
  • 1
  • 3
4

if you have nested schema

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

it's work for me

Nafiz Bayrak
  • 200
  • 2
  • 3
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)
    }
});
devzom
  • 676
  • 1
  • 9
  • 19
Shashwat Gupta
  • 5,071
  • 41
  • 33
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);
    });
});
Mr.Singh
  • 1,421
  • 6
  • 21
  • 46
Sehrish Waheed
  • 1,230
  • 14
  • 17
0
populate('lists.list')
populate(
 {
   path: "lists",
   populate : {
     path: "list",
     model: "List"
   }
 }
)
Siddhartha Mukherjee
  • 2,703
  • 2
  • 24
  • 29