SalmaFG
SalmaFG

Reputation: 2202

Node.js Error: Can't set headers after they are sent

I know this question already exists but the solutions I found didn't work for me. I am building a basic create function in Node.js. It first checks if the object already exists and if it doesn't, creates one. And I am getting this error even after I added else if and return to every condition. But it seems everything get executed regardless. This is my code:

controllers/shop.js:

var Shop = require('../models/shop').model;
module.exports = {
    create: function(req, res) {
        if(typeof(req) != 'object')
            return res.status(400).send({error: Error.InvalidInput});
        if(req.body.name === null) return res.status(400).json({error: Error.missingParameter('name')});
        Shop.findOne({name: req.body.name}, function(err, shop){
            if(err) return res.status(500).json({error: Error.unknownError});
            else if (shop) return res.status(409).json({error: Error.alreadyExists('Shop')});
        }).exec(Shop.create({name: req.body.name}, function(err, shop) {
            if (err) return res.status(500).json({error: Error.unknownError});
            else if (shop) return res.status(201).json(shop);
            else if (!shop) return res.status(400).json({error: Error.createFailed('Shop')});
        }));
    },
}

Upvotes: 1

Views: 115

Answers (2)

Aruna
Aruna

Reputation: 12022

Either you should pass a callback in the find method or use a function with exec but should not use both since they both are asynchronous and invoked at the same time.

You can refactor your code as below.

var Shop = require('../models/shop').model;
module.exports = {
    create: function(req, res) {
        if(typeof(req) != 'object')
            return res.status(400).send({error: Error.InvalidInput});
        if(req.body.name === null) return res.status(400).json({error: Error.missingParameter('name')});
        Shop.findOne({name: req.body.name}, function(err, shop){
            if(err) return res.status(500).json({error: Error.unknownError});
            else if (shop) return res.status(409).json({error: Error.alreadyExists('Shop')});
            else {
                Shop.create({name: req.body.name}, function(err, shop) {
                if (err) return res.status(500).json({error: Error.unknownError});
                else if (shop) return res.status(201).json(shop);
                else if (!shop) return res.status(400).json({error: Error.createFailed('Shop')});
        });
            }
        });
    },
}

Upvotes: 1

Paul Stoner
Paul Stoner

Reputation: 1512

Try setting variables for the response status and error/other messages in your if statements. then at the end of your create function return a single response object populated with the variables

var Shop = require('../models/shop').model;
module.exports = {
    create: function(req, res) {
        var status = 200;
        var message = "";
        if(typeof(req) != 'object')
            status = 400;
            message = Error.InvalidInput;
           ...
        return res.status(status).send({error: message});
          });
        }));
    },
}

Upvotes: 0

Related Questions