0

My intended use of the code is to check whether the database have a username and password that is passed to the function in the form of object User.

I initialize the success variable to false. And then I say if I find the record, then I will set it to true. However, the success variable is still false even when the record is found. The variable seems not be updating. Why? Also, How can I pass back the whole fetcheduser result while I can indicate whether the record is found or not foun? Many thanks

LoginSuccess : function (User) {

    var success = false;
    function isEmptyObject(obj) {
        return !Object.keys(obj).length;
    }

    function isEmptyObject(obj) {
        for (var key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                return false;
            }
        }
        return true;
    }
    var sql = require('mssql');
    var config = require('./configuration/sqlconfig');
    var fetcheduser;
    sql.connect(config).then(function () {
        console.log('Connected to DB');
        new sql.Request().query("SELECT * FROM dbo.LocalUser WHERE Username = '" + User.username + "' AND Password = '" + User.password + "';")
            .then(function (recordset) {
                if (isEmptyObject(recordset)) {
                    console.log("The User does not exist");
                } else {
                    fetcheduser = JSON.parse(JSON.stringify(recordset));
                    success = true;
                    console.log("The user is existed.");
                }
            }).catch(function (err) {
                //When errors come
            });
    }); 
    return success;
}
Grayson Ho
  • 35
  • 5
  • 1
    Let me ask you this: which comes first: setting success to true, or returning the result? Hint: it's probably not what you think. Also, your select statement is ripe for injection attacks - think of Bobby Tables... – Krease Mar 04 '17 at 17:44
  • It is asynchron: you return success, before it is set to true. – bugovicsb Mar 04 '17 at 17:44
  • so how can I make it set to be true before returning success? – Grayson Ho Mar 04 '17 at 18:03
  • This is a very popular question here (some version of it asked probably over a thousand times). Your `sql.connect()` and `sql.Request().query()` functions are asynchronous. That means your function returns BEFORE those operations have completed. Thus, you CAN'T return their result from your function. Instead, you have to use callbacks or promises to communicate back the result. All the options are described in the [other question](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) that yours was marked a duplicate of. – jfriend00 Mar 05 '17 at 00:09

2 Answers2

0

You'll need to return your Promise in order to get the correct success state. Like so...

function LoginSuccess() {
  var success = false;

  return sql.connect(config)
    .then(() => {
      return new sql.Request().query(...).then(
        () => success = true,
        () => success = false
      );
    })
    .then(() => {
      return success;
    });

}

LoginSuccess().then(success => ...);
Icid
  • 1,444
  • 1
  • 12
  • 21
0

Actually - variable is updating, but way too late - after you returned it. Try to make a result = { success: false } and check the result immediately after return and 5 secs later (or whatever appropriate), and you will see that it has changed: setTimeout(() => console.log(result), 5000)

Anyways, for production, go for the promise solution. Node 7.6 has finally now async/await, so you can get rid of the ugly ...then workarounds.

CFrei
  • 3,552
  • 1
  • 15
  • 29