Kim Kim - 1 month ago 6
Node.js Question

Node JS [Error: Can't set headers after they are sent.]

Hi lets say I have code like this:

router.get('/blablabla', function(req, res, next) {
model
.findOne({condition : req.body.condition})
.then(function(data) {
if(data) {
return res.send("data already exists");
}
else {
//DO mMODIFY THE DATA AND THEN SAVE THE DATA

return data.save();
}
})
.then(function(data) {
if(data) res.send("new data successfully saved");
})
.catch(function(err) {
console.log(err);
});
});


In current condition if data already exists, there will be error

**[Error: Can't set headers after they are sent.]
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)**


Why this error raised? based on my knowledge after res.send() is being called then all the later code below it will not be executed right?

I am return data.save() because I want avoid nesting statement.

UPDATE ALTERNATIVE SOLUTION



router.get('/blablabla', function(req, res, next) {
model
.findOne({condition : req.body.condition})
.then(function(data) {
if(data) {
return new Promise(function(resolve, reject) {
return resolve();
});
}
else {
//DO mMODIFY THE DATA AND THEN SAVE THE DATA
return data.save();
}
})
.then(function(data) {
if(data) res.send("new data successfully saved");
else res.send("data already exists");
})
.catch(function(err) {
console.log(err);
});
});

Answer

Your second .then() handler will still execute because the promise is not branched, it's chained so the chain keeps going and thus you will be doing two res.send() operations and that's what causes the error you see.

When you do:

return res.send("data already exists");

You are just returning a value from the .then() handler. Since that value is not a rejected promise, the promise stays resolved and the next .then() handler in the chain will execute.

You could do this:

router.get('/blablabla', function (req, res, next) {
    model.findOne({condition: req.body.condition}).then(function (data) {
        if (data) {
            return res.send("data already exists");
        } else {
            //DO mMODIFY THE DATA AND THEN SAVE THE DATA
            return data.save().then(function () {
                res.send("new data successfully saved");
            });
        }
    }).catch(function (err) {
        console.log(err);
    });
});

Or, you could do this:

router.get('/blablabla', function(req, res, next) {
    model
      .findOne({condition : req.body.condition})
      .then(function(data) {
        if (!data) {
          //DO mMODIFY THE DATA AND THEN SAVE THE DATA
          return data.save();
        }
        return data;
      })
      .then(function(data) {
        if(data) res.send("new data successfully saved");
        else res.send("data already exists");
      })
      .catch(function(err) {
        console.log(err);
      });
  });
Comments