Pritesh Mahajan Pritesh Mahajan - 3 months ago 26
Node.js Question

Node application crash if i use send or json

I am creating a IOS Application and in background we have used Node.js and Mongodb. I have create node application for creating user and send error and success response by jSon but if use

res.send
my node application will crash.
I have tried to found issue but not get yet and positive response. Below my all code.

Controller :


const nodemailer = require('nodemailer');
const passport = require('passport');
const User = require('../../models/User');





exports.ManuallySave = function(req,res)
{
if(req.body.my_token !== '')
{
User.findOne({ email: req.body.email }, (err, existingUser) => {
if (existingUser)
{
//res.setHeader('Content-Type', 'text/plain');
res.json({"status":'error',"msg":'Email address already exists.'});
}
});

User.findOne({ username: req.body.username }, (err, existingUserName) => {
if (existingUserName)
{
res.send({"status":'error',"msg":'Username already exists.'});
}
});

/* Save Action perform */
}
else
{
res.send({"status":'error',"msg":'Token is not available.'});
}

}


Console Error.


/var/www/node/MyApplication/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/var/www/node/MyApplication/node_modules/express/lib/response.js:718:10)
at ServerResponse.send (/var/www/node/MyApplication/node_modules/express/lib/response.js:163:12)
at ServerResponse.json (/var/www/node/MyApplication/node_modules/express/lib/response.js:249:15)
at ServerResponse.send (/var/www/node/MyApplication/node_modules/express/lib/response.js:151:21)
at /var/www/node/MyApplication/controllers/apis/userAppController.js:55:13
at model.<anonymous> (/var/www/node/MyApplication/node_modules/mongoose/lib/document.js:1875:20)
at next_ (/var/www/node/MyApplication/node_modules/hooks-fixed/hooks.js:89:34)
at fnWrapper (/var/www/node/MyApplication/node_modules/hooks-fixed/hooks.js:186:18)
at /var/www/node/MyApplication/node_modules/mongoose/lib/model.js:226:5
at /var/www/node/MyApplication/node_modules/mongoose/lib/model.js:135:7
at /var/www/node/MyApplication/node_modules/mongodb/lib/collection.js:504:5
at /var/www/node/MyApplication/node_modules/mongodb/lib/collection.js:666:5
at handleCallback (/var/www/node/MyApplication/node_modules/mongodb/lib/utils.js:96:12)
at /var/www/node/MyApplication/node_modules/mongodb/lib/bulk/unordered.js:473:9
at handleCallback (/var/www/node/MyApplication/node_modules/mongodb/lib/utils.js:96:12)
at resultHandler (/var/www/node/MyApplication/node_modules/mongodb/lib/bulk/unordered.js:420:5)
at /var/www/node/MyApplication/node_modules/mongodb-core/lib/wireprotocol/2_4_support.js:544:17
at nextTickCallbackWith0Args (node.js:420:9)
at process._tickCallback (node.js:349:13)


I have used res.send and res.json both but in both condition my application will crash.

Answer

That error is thrown when you are trying to call methods on res when you already called res.send. There is no guarantee that it res.send only will be called once in your code, which there must be. The block

User.findOne({ email: req.body.email }, (err, existingUser) => {
  if (existingUser) 
  {
    //res.setHeader('Content-Type', 'text/plain');
    res.json({"status":'error',"msg":'Email address already exists.'});
  }
});

User.findOne({ username: req.body.username }, (err, existingUserName) => {
  if (existingUserName) 
  {
    res.send({"status":'error',"msg":'Username already exists.'});
  }
});

will call res.send twice if you already have a user with both that email address and that username. You will have to do the other call within the first callback.

User.findOne({ email: req.body.email }, (err, existingUser) => {
  if (existingUser) 
  {
    //res.setHeader('Content-Type', 'text/plain');
    res.json({"status":'error',"msg":'Email address already exists.'});
  } else {
    checkUsername();
  }
});
function checkUsername() {
  User.findOne({ username: req.body.username }, (err, existingUserName) => {
    if (existingUserName) 
    {
      res.send({"status":'error',"msg":'Username already exists.'});
    } else {
      // save action
    }
  });
}

May I suggest you look into promise chains to handle the inevitable upcoming callback nesting?

Comments