Reputation: 1220
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");
});
};
Upvotes: 2
Views: 1769
Reputation: 17430
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);
res.json({ token: token });
} else {
res.status(400);
}
// like here
res.send();
});
});
});
});
From wikipedia, a callback is a piece of executable code that is passed as an argument to other code. There's nothing async by definition with a callback, but it's a really useful concept to use with async programming.
In JavaScript, a function can take a function reference as an argument which will serve as a callback.
function someFunction(callback) {
console.log("before async callback");
setTimeout(callback, 1); // calls the callback asynchronously
console.log("after async callback");
}
It could be called like this, using an existing function
function myExistingFunction() {
console.log("inside a callback");
}
someFunction(myExistingFunction);
or like this, using a function expression
someFunction(function(){
console.log("inside a callback");
});
Both calls to someFunction
would print the following to the console in that order:
before async callback
after async callback
inside a callback
Since someFunction
pass the callback to the async function setTimeout
, the callback is not called immediately, but only after the call stack finishes. So someFunction
completely finishes, then sometime later, our callback is called.
Take a look at
Upvotes: 1