0

I'm building an e-commerce like webapp in Nodejs-Express-MongoDB and what I want to achieve with the following code is to update the available stock of items after user's checkout.

The error comes when i'm trying to update the stock inside the for loop (without it performs as expected).

router.get('/checkout',function(req,res){
 if (!req.session.cart) {
  return res.redirect('cart');
 }
 else{
  var cart = new Cart(req.session.cart);
  var order = new Order({
    user: req.user,
    cart: cart
  });

  order.save(function(err,result)
  {
    var products = cart.generateArray();
    console.log(products);

    for(var i=0; i<products.length; i++)
    {
      Item.findById(products[i].item._id ,function(err,findedItem){
        if(err) {
          res.json(err);
        }
        if(findedItem) {
          var stock=findedItem.stock;
          console.log("* AVAILABLE STOCK: "+stock);

          if(stock < products[i].qty){
            req.flash('info', 'Ups, we can't serve this order');
            return res.redirect('/items/cart');
          }
          else{
            console.log("wrrkd!");
            Item.updateItem(products[i].item._id,products[i].qty);
          } 
        }         
      })
    }
    req.session.cart=null;
    res.redirect('/items/home');
  })
 } 
});

First of all with cart.generateArray(), I store in products an array containing all the purchased items. Then I start searching in my Item model (where all the store's items are) for the items, so that I can update the stock later.

So, if the quantity of at least one product is higher than that of the available one, I want it to stop and go back to the cart page. If not, just update the available stock and go to the home page.

Item.updateItem:

module.exports.updateItem = function(id,numItem,callback){
  Item.findById(id, function(err,findedItem){
    console.log("* UPDATING ITEM: "+findedItem.name);
    if(findedItem.stock > numItem){
      findedItem.stock -= numItem;
      findedItem.save(callback);
    } else if(findedItem.stock == numItem){
      Item.findByIdAndRemove(id,function(err) {
        if (err)
            res.send(err);
        else
          console.log("* DELETING ITEM: "+findedItem.name);
      });
    }
  })
}

Im getting the following error, I tried debugging but i have no clue how to solve it:

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (C:\...\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\...\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\...\node_modules\express\lib\response.js:267:15)
    at C:\...\routes\items.js:58:17
    at C:\...\node_modules\mongoose\lib\model.js:3930:16
    at _init (C:\...\node_modules\mongoose\lib\query.js:2000:14)
    at completeOne (C:\...\node_modules\mongoose\lib\query.js:1995:5)
    at Immediate.<anonymous> (C:\...\node_modules\mongoose\lib\query.js:1520:11)
    at Immediate._onImmediate (C:\...\node_modules\mquery\lib\utils.js:119:16)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)
Vishaal Shankar
  • 1,648
  • 14
  • 26
  • Possible duplicate of [Error: Can't set headers after they are sent to the client](https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client) – Ankit Manchanda Mar 23 '18 at 13:10

1 Answers1

0

If you write to output before setting the headers, the headers will be set automatically. Then when you redirect, the headers are already set, so it is not possible to redirect. You should only write to output when you dont want to redirect. So check for the need to redirection first. If you cant check for it(which is not a good thing anyway), you should keep the output in a buffer and then write it to the output when you are sure you don't need to redirect.

arashka
  • 1,226
  • 3
  • 17
  • 30