ravi ravi - 1 month ago 12
Node.js Question

Node Error : can't set headers after they are sent. How to solve?

After user click the login button, server closes itself by displaying an error that "Can't set headers after they are send." Any help?

Server.js file

app.put('/users/signin',function(req,res,next){
db.collection('users',function(err,usersCollection){
usersCollection.findOne({username:req.body.username},function(err,user){
bcrypt.compare(req.body.password,user.password,function(err,result){
if(result){
var token = jwt.encode(user,JWT_SECRET);
return res.json({token:token});
}else{
res.status(400).send();
}
})
});
});
res.send();
});


Controller from where i am making call to server..

$scope.signin = function(){
$http.put('/users/signin',{username:$scope.username,password:$scope.password})
.then(function(res){
$cookies.put('token',res.data.token);
$scope.currentUser = $scope.username;
alert("Successfully signed in");
},function(err){
alert("bad login credentials");
});
};

Answer

usersCollection.findOne is async and its callback is called after res.send(); as been called.

Move the res.send(); into the bcrypt.compare callback.

app.put('/users/signin', function(req, res, next) {
    db.collection('users', function(err, usersCollection) {
        usersCollection.findOne({ username: req.body.username }, function(err, user) {
            bcrypt.compare(req.body.password, user.password, function(err, result) {
                if (result) {
                    var token = jwt.encode(user, JWT_SECRET);
                    return res.json({ token: token });
                } else {
                    res.status(400).send();
                }

                // like here
                res.send();
            });
        });
    });
});