0

Use array.forEach to modify resultset from sequelize.

I want to loop over the shoppingCart returned, access database for each element and add some properties and return.

const promiseInvoices = [];

  await ShoppingCart.findAll({
    where: {
      // eslint-disable-next-line object-shorthand
      cart_id: cartItem.cart_id,
    },
  }).then(result => {
   result.forEach(cartItem2 => {
      const prod = Product.findByPk(cartItem2.product_id);
      console.log(prod);

      let cartItem3 = {};
      const total = prod.price * cartItem2.quantity;
      cartItem3.cart_id =  cartItem2.cart_id;
      cartItem3.product_id =cartItem2.product_id;
      cartItem3.attributes  =cartItem2.attributes;
      cartItem3.quantity  =cartItem2.quantity ;
      cartItem3.price = prod.price;
      cartItem3.name = prod.name;
      cartItem3.image = prod.image2;
      cartItem3.item_id = cartItem2.item_id;
      cartItem3.subtotal = total;

    return promiseInvoices.push(cartItem3);
    });
  });

Return the shoppingCart, access the database for each shoppingcart object and get the product to fill in the values of each shoppingCart item. The call to Product.findByPk is returning an usable promise like this:

Promise [Object] {
      _bitField: 0,
      _fulfillmentHandler0: undefined,
      _rejectionHandler0: undefined,
      _promise0: undefined,
      _receiver0: undefined }

1 Answer 1

1
  1. All Sequelize CRUD calls are asynchronous that means they return a promise so you have to await on them. The reason you get a Promise object returned instead of a product with details is because you are not waiting for your findByPk call to complete.

  2. The forEach construct does not support asynchronous operations. Even if you make your array.forEach callback asynchronous it will not work and still return Promise object instead of a product with details.

To solve this issue you need to wait for your async findByPk call and also use a loop that supports asynchronous operations. You can use the for...of loop for your use case.

const promiseInvoices = []

await ShoppingCart.findAll({
    where: {
        cart_id: cartItem.cart_id
    }
}).then(result => {

    // for...of loop that supports await
    for await (const cartItem2 of result){
        // Make sure to wait on all your sequelize CRUD calls
        const prod = await Product.findByPk(cartItem2.product_id)

        // It will now wait for above Promise to be fulfilled and show the proper details
        console.log(prod)

        let cartItem3 = {}
        const total = prod.price * cartItem2.quantity
        cartItem3.cart_id = cartItem2.cart_id
        cartItem3.product_id = cartItem2.product_id
        cartItem3.attributes = cartItem2.attributes
        cartItem3.quantity = cartItem2.quantity
        cartItem3.price = prod.price
        cartItem3.name = prod.name
        cartItem3.image = prod.image2
        cartItem3.item_id = cartItem2.item_id
        cartItem3.subtotal = total

        // Simple push will work in this loop, you don't need to return anything
        promiseInvoices.push(cartItem3)
    }
})
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect. I added async before result and it works fine. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.