3

I know the syntax of it and how it works, but I cannot understand the internal workings, why does a method chaining require another method at one time, but doesn't some other time?

This code works fine

const cart = await Carts.findById(cartId).populate('product');

But this code does not

let cart = await Carts.findById(cartId);
cart = await cart.populate('product');

And to make it work, we use the execPopulate method which works like this.

let cart = await Carts.findById(cartId);
cart = await cart.populate('product').execPopulate();

Now, as far as I have read method chaining in javascript, the code should run fine without the execPopulate method too. But I cannot seem to understand why populate does not work on existing mongoose objects.

Gaurav
  • 98
  • 3
  • 13

3 Answers3

18

Just a note for anyone reading this that execPopulate() has now been removed: https://mongoosejs.com/docs/migrating_to_6.html#removed-execpopulate

Yob
  • 245
  • 4
  • 9
3

Carts.findById(cartId); returns query Object.

When you use await Carts.findById(cartId); it returns the document as it will resolve the promise and fetch the result.

The await operator is used to wait for a Promise.


let cart = await Carts.findById(cartId); // cart document fetched by query
cart = await cart.populate('product'); // you can't run populate method on document

Valid case

const cartQuery = Carts.findById(cartId);
const cart = await cartQuery.populate('product');

.execPopulate is method on document, while .populate works on query object.

Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
1

You're using the populate() method on two different types of objects - ie a query and a document - which have their own specification for the method.

https://mongoosejs.com/docs/api/query.html#query_Query-populate https://mongoosejs.com/docs/api/document.html#document_Document-populate

IAmDranged
  • 2,890
  • 1
  • 12
  • 6