When POSTing to the database, I'm getting a "Can't set headers after they are sent error" When POSTing to the database, I'm getting a "Can't set headers after they are sent error" mongoose mongoose

When POSTing to the database, I'm getting a "Can't set headers after they are sent error"


Product.findById is asynchronous, and will end up calling next() multiple times, which will (most likely) result in attempting to send the response multiple times, which would result in the error you are seeing.

Typically (or always, possibly), you will only want to call next() once per middleware.

Try this:

"use strict";app.post('/makeSale', function(req, res, next){    var sale = new Sale();    sale.owner = req.body.user_id;    sale.total = req.body.total;    return Promise.all(req.body.items.map((item) => {        // pushs an item from the request object into the items array contained in the sale document        sale.items.push({            item: item.product_id,            itemName: item.name,            cartQuantity: parseInt(item.cartQuantity, 10), // adds cartQuantity to sale            price: parseFloat(item.priceValue)        });        return Product.findById(item.product_id).then((product) => {            //finds the item to be sold in the database and updates its quantity field based on the quantity being sold            product.quantity -= item.cartQuantity;             //resets the product's cartQuantity to 1            product.cartQuantity = 1;            return product.save();        });    }))    .then(() => {        //gives the sale a date field equal to current date        sale.date = new Date();        //saves and returns the sale        return sale.save();    })    .then(() => {        return res.status(200).json(sale);    })    .catch(next);});


In your route, you're calling next() for each saved product. You're also calling res.status(200).json(sale).

Calling next() tells Express that your route handler isn't interested in handling the request, so Express will delegate it to the next matching handler (or a generic Not Found handler if there isn't one). You can't subsequently call next() again, or send back a response yourself, because you already told Express that you're not interested.

You should rewrite req.body.items.map(...) so that it doesn't call next() at all.

One solution would be to use async.map(). You would then call either next(error) (if there is one) or res.json() in the final callback.


I use JS very rarely for backend, but usually that means you are attempting to set HTTP headers after you are already sent/sending the HTTP body.

Basically: Just make sure your headers are being sent before you print anything to the screen is what that error means.