Jiew Meng
Jiew Meng

Reputation: 88217

Mongoose populating children

I was learning mongoose, looking at the docs http://mongoosejs.com/docs/populate.html

Then I did:

# initialize some TodoLists and their todos

l1 = new TodoList
    name: "List 1"
l2 = new TodoList
    name: "List 2"

t1 = new Todo 
    title: "Todo 1"
    desc: "Hello 1"
    list: l1._id
t2 = new Todo 
    title: "Todo 2"
    desc: "Hello 1"
    list: l1._id
t3 = new Todo 
    title: "Todo 3"
    dueOn: new Date 2012,6,1
    completedOn: new Date 2012,6,1
    list: l1._id
t4 = new Todo 
    title: "Todo 4"
    desc: "Hello 4"
    list: l2._id

# save all
async.parallel [
    (done) -> l1.save(done)
    (done) -> l2.save(done)
    (done) -> t1.save(done)
    (done) -> t2.save(done) 
    (done) -> t3.save(done)
    (done) -> t4.save(done)
], (err) -> 
    if !err
            # debugging
    Todo.find {}, (err, todos) ->
        console.log todos
            # the populate
    TodoList.findOne({ name: "List 2" })
            .populate("todos")
            .exec (err, list) ->
                console.log list
                done()
    else
        done err

What I got was something like:

 [ { desc: 'Hello 1',
    list: 5026321c684d0a6b08000007,
    _id: 5026321c684d0a6b08000009,
    __v: 0 },
  { desc: 'Hello 1',
    list: 5026321c684d0a6b08000007,
    _id: 5026321c684d0a6b0800000a,
    __v: 0 },
  { dueOn: Sun Jul 01 2012 00:00:00 GMT+0800 (SGT),
    completedOn: Sun Jul 01 2012 00:00:00 GMT+0800 (SGT),
    list: 5026321c684d0a6b08000007,
    _id: 5026321c684d0a6b0800000b,
    __v: 0 },
  { desc: 'Hello 4',
    list: 5026321c684d0a6b08000008,
    _id: 5026321c684d0a6b0800000c,
    __v: 0 } ]
{ name: 'List 2',
  _id: 5026321c684d0a6b08000008,
  __v: 0,
  todos: [] }

Noice the last line, todos is not populated, I expect it to have Todo 4?

Upvotes: 1

Views: 2031

Answers (2)

Zeeshan Ahmad
Zeeshan Ahmad

Reputation: 5644

By using the following code you don't need to add todos key in your ListSchema. Just put the following code after defining ListSchema:

ListSchema.virtual('todos', {
    ref: 'Post',
    localField: '_id',
    foreignField: 'list'
});

Now to populate todos in list collection.

ListModel.find({}).populate('todos').exec((err, lists) => {
    if (err) return res.status(500).json(err);

    return res.status(200).json(lists);
});

Upvotes: 1

Michelle Tilley
Michelle Tilley

Reputation: 159105

Refs are not two-way. You've saved the refs to the Todos' parent Lists, but you're not storing refs to the Todos into the List.todos array.

Assuming your List schema is something like:

var ListSchema = new Schema({
  ...
  todos : [{ type: Schema.Types.ObjectId, ref: 'Todo' }]
});

Then you would need to do a list.todos.push(todo._id).

Upvotes: 2

Related Questions