0

I am consulting a document and with the result I consult another model but in the end, nothing is returning to me, the foreach does not wait for the await.

ShoppingCart.find({
   "userId": id
}).then(async ShoppingCart => {
   let distinctTypes = ShoppingCart[0].productsCart;
   distinctTypes.sort(function(r, u) {
      return r.manufacturerId > u.manufacturerId ? 1 : r.manufacturerId < u.manufacturerId ? -1 : 0
   });
   let products = [];
   let data2 = await distinctTypes.forEach(async function(thisType) {
      let id = thisType.productId;
      let data = await Product.findById(id).then(Product => {
         thisType.productId = Product;
         products.push(thisType);
         return products;
      });
      return data; ///at this point the information is correct
   });
   return data2;
});

"data": null

kedar sedai
  • 1,687
  • 3
  • 16
  • 25
andres henao
  • 21
  • 1
  • 4

2 Answers2

0

This happens because forEach does not executes in a synchronised way. Use For of loop instead.

Detailed answer : - Using async/await with a forEach loop

royalbhati
  • 296
  • 3
  • 10
0

You are correct that Array.prototype.forEach does not wait. Instead, you should use Array.prototype.map and Promise.all

ShoppingCart.find({
   "userId": id
}).then(async cart => {
   let distinctTypes = cart[0].productsCart;
   distinctTypes.sort(function(r, u) {
      return r.manufacturerId > u.manufacturerId ? 1 : r.manufacturerId < u.manufacturerId ? -1 : 0
   });
   const distinctTypesWithProducts = await Promise.all(
     distinctTypes.map(async function(thisType) {
        let id = thisType.productId;
        const product = await Product.findById(id)
        thisType.product = product // changed assignment of product to thisType.product
        return thisType
     });
   );
   return distinctTypesWithProducts;
});

You could simplify the above with a project I started. Contributions are welcome.

const { pipe, assign, map, get } = require('rubico')

// userId => cart
const findCartByUserID = userId => ShoppingCart.find({ userId })

// [distinctType] => [distinctType] sorted
const sortDistinctTypes = distinctTypes => distinctTypes.sort((r, u) => {
  return r.manufacturerId > u.manufacturerId ? 1 : r.manufacturerId < u.manufacturerId ? -1 : 0
})

// distinctType => distinctTypeWithProduct
const assignProduct = assign({
  product: pipe([
    get('productId'), // distinctType => productId
    Product.findById, // productId => product
  ]), // distinctType.product = product; return distinctType
})

// userId => [distinctTypeWithProduct, distinctTypeWithProduct, ...]
const getDistinctTypesWithProductFromUserID = pipe([
  findCartByUserID,
  // userId => cart

  get([0, 'productsCart']),
  // cart => distinctTypes

  sortDistinctTypes,
  // distinctTypes => sortedDistinctTypes

  map(assignProduct),
  // sortedDistinctTypes => [distinctTypeWithProduct, distinctTypeWithProduct, ...]
])

getDistinctTypesWithProductFromUserID(id)
richytong
  • 2,387
  • 1
  • 10
  • 21