1

I have a function that I am calling and I need to make some database queries inside of that function. What is the best way to do this in node? Currently I just make a request and assign the return value to a variable but this results in the variable not being set. Example:

// bunch of code
var is_member = false;
mysql.query('SELECT EXISTS ( SELECT * FROM `qazusers` WHERE `qazemail` = ? OR `otheremail` = ? LIMIT 1)', [emailaddress, emailaddress], function (err, result) {
    if (err) {
        logger.info('Error checking. ', err);
    }
    logger.info('checkmembership: ', result);
    if (result[0] === 1) {
        is_member = true;
    }
// bunch more code finishing out the function this is inside

Once the containing function is done running, is_member is always false. I assume this is due to the asynchronous nature of node but, what is the best way to handle this? I have read up a bit on Promises (like the Q library) but I am still not sure of the best way to handle setting a variable inside of a nodejs based function. How would this be done, ideally?

Lothar
  • 3,409
  • 8
  • 43
  • 58
  • Try checking out http://stackoverflow.com/questions/22994589/nodejs-express-routes-and-mysql – Steve Apr 10 '14 at 20:44
  • So I would need to nest the rest of the function content inside the success portion of the mysql call? And if I have to make 3 or 4 mysql calls they would each then have to be nested deeper and deeper? That seems awkward and not ideal? – Lothar Apr 10 '14 at 20:48
  • Yes, welcome to the world of asynchronous programming! :-) If you aren't comfortable with solutions like that, either pass function references in rather than anonymous functions, or look at Bergi's answer below for a Promises-based solution. – Scott Sauyet Apr 10 '14 at 20:53

1 Answers1

2

Promises are a fine approach. You'd use them like this:

var promise = Q.ninvoke(mysql, "query", 'SELECT EXISTS ( SELECT * FROM `qazusers` WHERE `qazemail` = ? OR `otheremail` = ? LIMIT 1)', [emailaddress, emailaddress])
var moreresults = promise.then(function(result) {
    logger.info('checkmembership: ', result);
    return result[0] === 1;
}).then(function(is_member) {
    // bunch more code finishing out
    return more;
});
moreresults.catch(function(err) {
    logger.info('Error checking. ', err);
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • So are you saying that all of the code dependent on the result of the query has to be nested inside the `then` portion? If I need to make 3 or 4 different queries to get values I would need to progressively nest them inside these `then` calls? – Lothar Apr 10 '14 at 21:31
  • Logging the value of `result` gave the query itself and a bunch of numbers that related to nothing and logging `is_member` showed it was not defined. I'm sure I'm missing something but this did not get me a result that made sense. – Lothar Apr 10 '14 at 22:21
  • The resolution values of the promises are passed as parameters to the `then` callback - sorry I've used the identifier `result` twice. – Bergi Apr 10 '14 at 23:01
  • Yes, all code that depends on the async result needs to go in a `then` callback. But you don't need to nest it, you can *unwrap* them - [promises aren't only callbacks](http://stackoverflow.com/a/22562045/1048572) – Bergi Apr 10 '14 at 23:02