0

I have a sqlite3 js controller function for node.js :

exports.findUser=function findUser(user){
var temp ;
var db = new sqlite3.Database('kitchen.db');
var stmt_user_find = "SELECT * FROM user WHERE un = ?";
db.all(stmt_user_find,user,save);
function save(err, rows) {
    if (err) throw err;
    console.log(rows);
    temp = rows;
}
db.close();
return temp;

}

and another function in router using Express:

app.post('/login', function (req, res){
    var un=req.body.un;
    var pw=req.body.pw;

        console.log('router '+db.findUser(un));

});

The result of console is :

router undefined
[ { un: 'as', em: 'sss', pw: 'sss' } ]

The second function aims to get the value from sqlite database, but the result from console shows that the 'return temp' statement is executed firstly and return to the second function, and later the inner function (save) of findUser function is executed. So why it is like this and how can I get value from database?

Thank you, I have tried for hours in this problem.

Hope
  • 36
  • 4

1 Answers1

-1

Node will not wait for the database call to complete to continue executing code, so you have to force it to do so. The code you posted returns the variable 'temp' before it is defined, then the callback (your 'save' function) assigns a value to it after the database call completes. Try this:

exports.findUser=function findUser(user){
    var temp ;
    var db = new sqlite3.Database('kitchen.db');
    var stmt_user_find = "SELECT * FROM user WHERE un = ?";

    function save(err, rows) {
        if (err) throw err;
        console.log(rows);
        temp = rows;
        db.close();
        return temp;
    }
    db.all(stmt_user_find,user,save);
}

Now the findUser function will not return until after the database call completes because the return statement is inside the callback. If you would like to learn more, this link is a great place to start.

Edit: My apologies, of course the above will not work. You need to give yourself a callback. Try this:

exports.findUser=function findUser(user, callback){
    var temp ;
    var db = new sqlite3.Database('kitchen.db');
    var stmt_user_find = "SELECT * FROM user WHERE un = ?";
    var finduser = this;

    db.all(stmt_user_find,user, function(err, rows){
        if (err) throw err;
        console.log(rows);
        temp = rows;
        db.close();
        return callback(temp);
    });
}

And in your route:

app.post('/login', function (req, res){
    var un=req.body.un;
    var pw=req.body.pw;

    db.finduser(un, function(found_user) {
       console.log('router '+db.findUser(un));
    });
});

I'm not set up with your environment, so I can't test the code, but hopefully the basic idea is clear.

remyp
  • 259
  • 1
  • 4
  • I tried this but the 'return' is for the function 'save', not the main function 'findUser', so the result is still the same... – Hope Apr 13 '15 at 00:21
  • You should be able to solve this if you give yourself a callback. I've edited my answer to demonstrate how to do so. – remyp Apr 13 '15 at 01:05
  • This is the answer!! That works, callback is a very smart method in asynchronous environment, I also found another [way](http://stackoverflow.com/questions/17954743/node-js-and-express-passing-sqlite-data-to-one-of-my-views) but I did not try it and it seems breaking the clear structure of database controller. Thank you very much! – Hope Apr 13 '15 at 01:48
  • Glad I could help! Please accept the answer if you find it suitable. – remyp Apr 13 '15 at 04:07