Search code examples
node.jsmariasql

return value from a function with asynchronous commands


I'm writing a NodeJS v0.10 application with MariaSQL.

i want to create a function that returns the id of a row, and if the row doesn't exist, to create it and then return the id.

this is what I have so far:

TuxDb.prototype.createIfNEDrinkCompany = function(drinkCompany) {
 this.client.query("insert into drink_company(drink_company_name) values(:drink_company) on duplicate key update drink_company_id=drink_company_id",
    {'drink_company' : drinkCompany})
    .on('result',function(res) {
    res.on('end',function(info){
        if (info.insertId > 0) {
                return info.insertId;
        } else {
            this.client.query("select drink_company_id from drink_company where drink_company_name = :drink_company",{'drink_company' : drinkCompany})
                .on('result',function(res){
                    res.on('row',function(row){
                        return row.drink_company_id;
                    });
                });
        }
    });
    });

}

now the problem is that since it's asynchronous, the function ends before the value is returned.

how can I resolve this issue ?


Solution

  • The standard way in nodejs of dealing with async code is to provide a callback function as a last argument to your method and call it whenever your asynchronous finishes. The callback function standard signature is (err, data) - you can read more about here: Understanding callbacks in Javascript and node.js

    Rewriting your code:

    TuxDb.prototype.createIfNEDrinkCompany = function(drinkCompany, callback) { 
     this.client.query("insert into drink_company(drink_company_name) values(:drink_company) on duplicate key update drink_company_id=drink_company_id",
        {'drink_company' : drinkCompany})
        .on('result',function(res) {
        res.on('end',function(info){
            if (info.insertId > 0) {
                    callback(null, row.drink_company_id);
            } else {
                this.client.query("select drink_company_id from drink_company where drink_company_name = :drink_company",{'drink_company' : drinkCompany})
                    .on('result',function(res){
                        res.on('row',function(row){
                            callback(null, row.drink_company_id);
                        });
                    });
            }
        });
        });
    
    }
    

    and then in the code calling your method

    db.createIfNEDrinkCompany(drinkCompany, function(err, id){
        // do something with id here
    })