How to I stop executing the rest and return error message if error happens in Nodejs?

I am building shopping app with node and react but I’m having and issue. I am comparing number of products in my stock and number of product ordered, here is what I did:

export const addOrderItems = asyncHandler(async (req, res) => {
  const {
    orderItems,
    mobile,
    paidAmount,
    discountAmount,
    totalPrice,
  } = req.body

  if (orderItems && orderItems.length === 0) {
    res.status(400)
    throw new Error('No order items')
    return
  } else {
    const order = new OrderModel({
      orderItems,
      user: req.user._id,
      mobile,
      paidAmount,
      discountAmount,
      totalPrice,
    })

    order.orderItems.map(async (item) => {
      const product = await ProductModel.findById(item.product)

      if (item.qty <= product.countInStock) {
        product.countInStock = product.countInStock - Number(item.qty)
        await product.save()
      } else {
        console.log(`${item.name}  is out of stock`)
      }
    })


// I want to stop this action if the product is out of stock
    const createdOrder = await order.save()
    res.status(201).json(createdOrder)
  }
})

For Example: item.qty = 4 which is qty product requested from the user and product.countInStock = 2 which is my product qty in the store

Answer

I recommended using for loop instead of .map to check number of products.

And I change a little logic of your function, I commented in bellow code version:

export const addOrderItems = asyncHandler(async (req, res) => {
  const {
    orderItems,
    mobile,
    paidAmount,
    discountAmount,
    totalPrice,
  } = req.body

  if (orderItems && orderItems.length === 0) {
    res.status(400)
    throw new Error('No order items')
  } else {
    const order = new OrderModel({
      orderItems,
      user: req.user._id,
      mobile,
      paidAmount,
      discountAmount,
      totalPrice,
    })

    // Make sure all products are available at first
    const products = []
    for (const item of order.orderItems) {
      const product = await ProductModel.findById(item.product)
      if (item.qty <= product.countInStock) {
        product.countInStock = product.countInStock - Number(item.qty)
        products.push(product);
        // Not save the product here, you can not make sure that the order is success
      } else {
        // One of them is out of stock, stop immediate
        res.status(400)
        throw new Error(`The product ${product.name} is out of stock`) // product.name ?
      }
    }

    // Save order at first, You need read about transaction for these actions
    const createdOrder = await order.save()

    // .map with async callback function will return an array of promise
    await Promise.all(products.map(async (pro) => await pro.save()))

    res.status(201).json(createdOrder)
  }
})

Leave a Reply

Your email address will not be published. Required fields are marked *