Skip to content

Moongose after find, object.map is not returning key

I have a code that after find and populate, I will then add a new key (‘order_date’) based on createdAt.

const summaryGetOrders = async (start_date, end_date) => {
  let orders = await Order.find({ createdAt: { $gte: new Date(start_date), $lt: new Date(end_date) } }).populate(
    'orderdetails_id'
  );

  await Promise.all(
    orders.map(async (i, index) => {
      i.order_date = i.createdAt;
      // orders[index] = i
      // orders[index].order_date = i.createdAt
    })
  );

  console.log(orders);

  return orders;
};

I have checked with console.log(i.createdAt), it do have the date element in the i, but when I do console.log(orders), it is not retunring me order_date.

Is it caused by the async await function? I am doing this because my express boilerplate automatically removes the createdAt key via the toJSON function on my model. I wish not to modify because my code is tailor not to deal with createdAt.

Answer

By default, Mongoose queries return an instance of the Mongoose Document class, not plain old JavaScript objects (POJOs) so some fields that isn’t defined in the schema will not show when you console.log it (You can check for more info here).

To solve that, you can use .lean() on your query to make the result become plain javascript objects.

Beside, you don’t need to use Promise.all because map is not asynchronous and using forEach may be better in this case.

const summaryGetOrders = async (start_date, end_date) => {
  let orders = await Order.find({ createdAt: { $gte: new Date(start_date), $lt: new Date(end_date) } }).populate(
    'orderdetails_id'
  ).lean();


  orders.forEach((i, index) => {
    i.order_date = i.createdAt;
    // orders[index] = i
    // orders[index].order_date = i.createdAt
  })

  console.log(orders);

  return orders;
};