1

I have a Node.js function to fetch some value from DB table

var GetPoints = function(ibmdb, dbConnection, msisdn) {
    ibmdb.open(dbConnection, function(err, conn) {
        if (err) {
            //Error
        } else {
            conn.query('SELECT id,msisdn,points FROM t_points WHERE msisdn =' + msisdn, function(err, data) {
                console.log(err);
                if (!err) {
                    conn.close(function(err) {
                        if (!err) {}
                    });
                    consele.log(data);
                    //return data[0].POINTS;
                } else {
                    //Error
                }
            });
        }
        console.log("points" + points);
    });
}

I want to know how I can access the data object when I call this function from outside

 var data = GetPoints(ibmdb, dbConnection, msisdn);

The value is coming correctly when I do a console.log

5
  • No Return data is not working..I trued to use return data after line console.log(data). But it seems the value is only valid for the context of the internal function Commented Jun 27, 2015 at 10:18
  • You mean from an async function, i.e. conn.query's callback function? You can't unfortunately. Your data is only available inside that callback. Commented Jun 27, 2015 at 10:19
  • There is no way I can get the data[0].POINTS outside the context? Commented Jun 27, 2015 at 10:22
  • assign a variable with outside scope with the return value. take a small interval for checking the variable and if set do something. Commented Jun 27, 2015 at 10:23
  • Problem is that data is available AFTER query is executed. But GetPoints returns when query is started. So you can store data somewhere and wait query completion or use it inside callback. Commented Jun 27, 2015 at 10:26

2 Answers 2

6

You can't return the value from an async function directly. Promises are generally used this situation. You return a promise which can later be called .then upon to retrieve the said value.

var Promise = require('bluebird');
var GetPoints = function(ibmdb, dbConnection, msisdn) {
    // return a Promise
    return new Promise(function(resolve){
        ibmdb.open(dbConnection, function(err, conn) {
            if(err) throw err; // throw the error for it to be caught
            …
            conn.query('SELECT …', function(err, data) {
                if(err) throw err;
                …
                consele.log(data);
                //return data[0].POINTS;
                resolve(data);
}); }); }); }

GetPoints().then(function(data){
    // do something with data
}).catch(function(err){
    // handle err
});

Additionally, Bluebird has a promisify function that turns an async function (that takes a callback) into a function that returns a Promise. It makes the above code much simpler:

Note: Although I was reluctant because if you're using MySQL with which the promisification could be a little tricky: 1, 2. But For now I've added .promisifyAll where it might seem redundant as it will likely be executed more than once, but hopefully bluebird's promisification is smart enough to handle this. Nonetheless if you manage to promisify more efficiently you can just remove the redundant promisifyAll and just use X.yyyAsync methods as described:

function GetConnection(ibmdb, dbConnection, msisdn){
    Promise.promisifyAll(ibmdb);
    return ibmdb.openAsync();
}

function getData(conn){
    Promise.promisifyAll(conn);
    return conn.queryAsync('SELECT …');
}

GetConnection()
.then(getData)
.then(function(data){
    // do something with data        
})
Sign up to request clarification or add additional context in comments.

3 Comments

Bluebird's promisify functions could likely be used here to avoid creating new Promises directly (which often aren't needed and are prone to mistakes).
@MattHamann Excellent point. I love promisification myself, but I was reluctant in this case because I found that with MySQL it can be a little tricky: 1, 2. Nonetheless, I've expanded on both the promisification part and the related issue with mysql. I also corrected the mistake of not throwing the errors (hopefully that was the only mistake).
all i could return is a promisify object.
0

The callback function you gave after the SQL query gets executed asynchronously. Instead of trying to get that data outside the function, you should try to perform whatever you need to do inside. Keep in mind you can create another function and call it with the data to continue your work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.