7

I'm learning Node.js and I'm just starting to work with some MySQL connections. I have a function which is supposed to get a set of rows from the database, which it does correctly. However, I don't know how to return that set of rows afterwards. I tried two options (both explained in comments within the code segment below.

function fetchGameList(){
    var ret = 0;

    connection.query("SELECT * from tbl", function(err, rows, fields) {
        //some stuff happens here, and 'ret' is set to a vlue, for instance
            //ret = 7;
        //ret has the value 7 here, but if I put 'return ret' here, nothing is returned
    });

    return ret; //returns 0 because Node is asynchronous and the query hasn't finished yet
}

So, the question is, how do I return the correct value of ret (7 in this case)? Am I even structuring this properly?

sveti petar
  • 3,637
  • 13
  • 67
  • 144

1 Answers1

11

You need to pass a callback into your function. Convention is that the callback takes an error (or null if none happened) as the first argument, and results as other arguments.

function fetchGameList(callback) {
    var ret;

    connection.query("SELECT * from tbl", function(err, rows, fields) {
        if (err) {
            // You must `return` in this branch to avoid using callback twice.
            return callback(err);
        }

        // Do something with `rows` and `fields` and assign a value to ret.

        callback(null, ret);
    });
}

You can now do something along the lines of:

function handleResult(err, result) {
    if (err) {
        // Just an example. You may want to do something with the error.
        console.error(err.stack || err.message);

        // You should return in this branch, since there is no result to use
        // later and that could cause an exception.
        return;
    }

    // All your logic with the result.
}

fetchGameList(handleResult);
qubyte
  • 17,558
  • 3
  • 30
  • 32
  • You'll realise quickly that this can become unmanageable. I recommend the [async](https://npmjs.org/package/async) library for handling long chains of asynchronous functions. – qubyte Jan 18 '14 at 17:15
  • I'm worried that, when I have 5 functions like this, I will have to call each one like this and make 5 "layers" of functions so to speak. As you said, this can easily become unmanageable. I mean, I can write it, but good luck to anyone trying to modify it later on. The "async" library looks like just what I need, at first glance it looks like I'll want to use the `.series` flow control in these cases. – sveti petar Jan 18 '14 at 18:03
  • 1
    You're spot on. `async.series` is the single most useful method of the library. Try to avoid `async.waterfall`. It looks nice at first, but makes modifications later more difficult. Try to name your functions too, rather than write inline anonymous functions. This improves readability and also stack traces when things go wrong. – qubyte Jan 18 '14 at 18:07