beNerd
beNerd

Reputation: 3374

how does the populate method works in mongoose?

I have the following schemas defined:

module.exports.contact=Schema({

_id:Number,

name: String,

email: String,

contactNumber: String,

company:String,

_invoices:[{ type: Schema.Types.ObjectId, ref: 'invoice' }],


},{strict:false});


module.exports.invoice=Schema({

_contact: { type : Number, ref: 'contact'},

_id:Number,


invoiceNumber:Number,


},{strict:false});

And following data is inserted in mongodb:

    //CONTACT COLLECTION
    {_id:1,name:"Mrinal Purohit",email:"[email protected]",contactNumber:"+919016398554",company:""}
    //INVOICE COLLECTION
    { _id:1, invoiceNumber:3 , _contact:1 }

Only one document is there in the respective collections. Now i attempt this:

models.contact.find().populate('_invoices').exec(function(err,data){
        console.log(data);
        res.send(data)
    });

I get the following:

[ { _id: 1,
    name: 'Mrinal Purohit',
    email: '[email protected]',
    contactNumber: '+919016398554',
    company: '',
    __v: 0,
    _invoices: [] } ]

I actually expected the invoices to be populated in the array. Is there something wrong with the schema definition? I am unable to completely understand the .populate function of mongoose :(

Upvotes: 0

Views: 1119

Answers (2)

C Blanchard
C Blanchard

Reputation: 1063

Your _id type is mismatched

In your invoice schema _id is defined as a Number. However in your definition of _invoices in the contact schema, you've selected the Schema.Types.ObjectId type

Try changing the type of _invoices to Number, e.g.

module.exports.contact=Schema({
  _id:Number,
  name: String,
  email: String,
  contactNumber: String,
  company:String,
  _invoices:[{ type: Number, ref: 'invoice' }],
},{strict:false});

Alternatively, you can let Mongoose set _id for you by omitting the _id property in your schemas (so you can leave _invoices unchanged). It would save you a bit of work in generating unique IDs and it also has a bunch of other useful properties (like the embedded timestamp)

Update

damphat is also correct in pointing out the other error (which I missed). According to the data you're inserting, you've haven't pushed the _id of your new invoice into the relevant contact document

Here's a sketch of how to create an invoice while properly updating the relevant contact

Invoice.create(invoiceAttributes, function (err, invoice) {
    if (err) // Handle your error
    Contact.findOne({ _id: invoiceAttributes._contact}, function (err, contact) {
        if (err) // Handle your error
        contact._invoices.push(invoice._id); // The important step you were missing
        contact.save(); // Insert your callback
    });
});

Upvotes: 1

damphat
damphat

Reputation: 18956

Just add 1 line _invoices: [1] to the contact document:

{
    _id: 1,
    name: "Mrinal Purohit",
    email: "[email protected]",
    contactNumber: "+919016398554",
    company: "",
    _invoices: [1]
}

and correct the typo in your contact schema as well.

Upvotes: 0

Related Questions