Reputation: 7100
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
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
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
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