javascriptmongoosemodelassociationspopulate

Mongoose Populate() not populating array of ObjectIds


I have just started with Mongoose and am trying to get populate() to work using a very basic example. Currently I have two Models, a car and an Owner model.

Owner

const mongoose = require('mongoose')

module.exports = mongoose.model('Owner', mongoose.Schema({
  name: String,
  cars: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Car' }]
}))

Car

const mongoose = require('mongoose')

module.exports = mongoose.model('Car', mongoose.Schema({
  brand: String
}))

The idea is that an owner should be able to own several cars. So I store an ObjectId reference for every car in the owner's cars array.

Owner.findById(ownerId, function (err, owner) {
  if (err) console.log(err)

  const c = new Car({ brand: 'Toyota' })

  owner.cars.push(c)
  owner.save()
  console.log(owner.cars) // prints out an array containing multiple car _ids, everything working so far
})

Then I want to populate the cars array with the data from Car Model (their brands). Running the populate below however only returns one document [{"_id":"....","brand":"Toyota","__v":0}]. The array length is 1, although there are obviously a lot of Car ids stored if I check the database or just skip the populate call.

Owner.findById(ownerId).populate('cars').exec(function (err, owner) {
  if (err) console.log(err)
  console.log(owner) //this only returns one object 
})

What am I doing wrong? As you can tell I am a bit confused and would appreciate any help. Thank you!


Solution

  • The first issue was likely related to the ObjectIds being wrong. So I removed everything from MongoDB and started over (I did not change anything in the schemas so the issue didn't lie here). With the DB being empty, I created a new Owner, and pushed two Car ids to the "cars" array. Then I ran populate() again and it returned

    [
      {
        cars: [ [Object], [Object] ],
        _id: 5e375dc926cd72641cd60d74,
        name: 'James',
        __v: 0
      }
    ]
    

    Initially I had some difficulties understanding why I couldn't access the "cars" array/why it always returned defined, but then I realized, thanks to Nathan Romano in https://stackoverflow.com/a/25004168/2768479 that it was because the cars "are nested more than 2 levels, so by default the output is represented by "[Object"]. Simply by running

    owner[0].cars
    

    I got the cars I was looking for, and populate() was working as intended.