AdityaParab
AdityaParab

Reputation: 7100

How to return this value?

I am building a mobile app using phonegap, jQuery and jQuery mobile. I want to use SqLite database in my app for storing some user information. (I can't use local storage i want to do search/sort operations on the data)

This is the code I am working on to get this done,

function getAccountInformation(){
    var accounts = {};
    db.transaction(function(transaction) {
        transaction.executeSql('SELECT * FROM account;', [], 
            function(transaction, result) { 
                if (result != null && result.rows != null) { 
                    for (var i = 0; i < result.rows.length; i++) {
                        var item={};
                        var row = result.rows.item(i); 
                        for(var prop in row){
                            item[prop]=row[prop]
                        }
                        accounts[i]=item;
                    }
                }
            },errorHandler
        );
    },errorHandler,nullHandler);
    console.log(JSON.stringify(accounts));
}

If I put this console.log(JSON.stringify(accounts)); after the end } of the for loop it shows proper output.

But if I put it where it is right now the {} is printed as an output.

How can I make getAccountInformation() function return that accounts object to my other function? Where I will use jQuery to render the output.

What I want to do is return this accounts object simply by wrting return accounts;

Upvotes: 0

Views: 295

Answers (3)

Denis Mazourick
Denis Mazourick

Reputation: 1455

Because the SqLite functions are asynchronous you cannot just return the value.

I would make the getAccountInformation receiving a callback as below:

function getAccountInformation(callbackfn)
{
    db.transaction(function(transaction),
        .....,
        function (transaction, result)
        {
            if (result != null)
            {
               callbackfn(result);
            }
        });
}

In such way you will get your function called when the db request executed.

Upvotes: 1

Mattias Buelens
Mattias Buelens

Reputation: 20159

db.transaction and transaction.executeSql produce their results asynchronously through the use of callback functions. This means that your getAccountInformation function will return immediately and will not wait for the transaction to complete (as in a synchronous call).

It's probably easier to simply pass in a callback function as an argument of your getAccountInformation and run that function when the accounts array is populated. Therefore, change your function signature to getAccountInformation(callback) and replace the executeSql callback with:

        function(transaction, result) { 
            if (result != null && result.rows != null) { 
                for (var i = 0; i < result.rows.length; i++) {
                    var item={};
                    var row = result.rows.item(i); 
                    for(var prop in row){
                        item[prop]=row[prop]
                    }
                    accounts[i]=item;
                }
                callback(accounts); // Call callback function with populated accounts
            }
        }

You can then call this function with:

getAccountInformation(function(accounts) {
    // Do something with the accounts
});

There are fancier ways such as jQuery Deferreds and Promises which makes working with asynchronous functions easier, but you still need to understand why this exists. By using asynchronous actions, your application stays responsive while waiting for results.

Upvotes: 0

Boldewyn
Boldewyn

Reputation: 82734

That depends on when the function is called. When it is called asynchronously (like an AJAX request) you're out of luck. In that case I suggest you read about jQuery deferreds.

A code snippet based on deferreds could look like this:

var deferred = new jQuery.Deferred();
var accounts = {};

deferred.done(function(data) {
    // process your data here
});

db.transaction(function(transaction) {
    transaction.executeSql('SELECT * FROM account;', [], 
        function(transaction, result) { 
            if (result != null && result.rows != null) { 
                for (var i = 0; i < result.rows.length; i++) {
                    var item={};
                    var row = result.rows.item(i); 
                    for(var prop in row){
                        item[prop]=row[prop]
                    }
                    accounts[i]=item;
                }
                deferred.resolve(accounts); // let the "done" function get called
            } else {
                deferred.reject();
            }
        }, errorHandler
    );
},errorHandler,nullHandler);

Upvotes: 1

Related Questions