0

I am using node js $http to handle http post request that authenticate the user by mail and password with the DB (mongoDB).

The problem is that the DB query takes time and therefore not sync with the http call. I am returning back http with req==undefiend because I am not waiting (with promise or something like that, to the db query to finish).

Since I am new to JS and node JS I will appreciate if someone could help me fix my code. Thanks!

Important: it will work if I will send the req with true or false value straight from the inner function --> I know that! but.. I want it be written in a more generic way - I want the http logic not involved with the db logic.

app.post('/authenticate_user', function(req, res){
    var mail = req.body.Mail;
    var password = req.body.Password;
    res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate, max-age=0");
    var isValid=authenticate_user(mail, password);

console.log("isValid-->"+isValid); 
    // I get undefiend since at this time the db did nor finish... 

    res.json(isValid);
});
var authenticate_user=function(mail, password){
    var query = user_details.find({'Mail': mail});
    query.exec( function(err, docs){
        if (docs.length==0) {
            return false;
        }
        else{
            return(docs[0].Password==password);
        }
    }); 
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Matoy
  • 1,738
  • 3
  • 22
  • 53

2 Answers2

1

The "good node.js /event driven" way of doing this is to not wait.

Like almost everything else when working with event driven systems like node, your function should accept a callback parameter that will be invoked when then computation is complete. The caller should not wait for the value to be "returned" in the normal sense, but rather send the routine that will handle the resulting value:

function(query, callback) {
  myApi.exec('SomeCommand', function(response) {
    // other stuff here...
    // bla bla..
    callback(response); // this will "return" your value to the original caller
  });
}

So you dont use it like this:

var returnValue = myFunction(query);

But like this:

myFunction(query, function(returnValue) {
  // use the return value here instead of like a regular (non-evented) return value
});
Vivek Sharma
  • 164
  • 1
  • 8
0

As far as your code goes, this is probably the easiest way - just pass your HTTP res object into your DB promise and resolve it once the DB result comes in:

app.post('/authenticate_user', function(req, res) {
  var mail = req.body.Mail;
  var password = req.body.Password;
  res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate, max-age=0");
  authenticate_user(res, mail, password);
});
var authenticate_user = function(res, mail, password) {
  var query = user_details.find({
    'Mail': mail
  });
  query.exec(function(err, docs) {
    var isValid = false;
    if (docs.length == 0) {
      isValid = false;
    }
    else {
      isValid = (docs[0].Password == password);
    }
    res.json(isValid);
  });
};
Maksym
  • 1,430
  • 1
  • 11
  • 13