Reputation: 73
I have a big problem. I know it's about callback, closure but I don't know how to solve the problem. Here is my code
$.Model.extend('Article',
{
findAll : function(params, success, error){
var result = []
db.transaction(function(tx) {
tx.executeSql('select * from contents', [],function(tx, rs) {
for(var i=0; i<rs.rows.length; i++) {
var row = rs.rows.item(i)
result[i] = {
id: row['id'],
title: row['title'],
body: row['body']
}
}
})
})
//here result is undefined
alert(result)
return result
}
})
//undefined
var view = Article.findAll
I know that executeSql is asynchronous function, but I don't know how to save and return result of executeSql. I use javascript mvc and HTML offline database.
Thank you for your help
Upvotes: 4
Views: 21143
Reputation: 2511
Your trying to use the result synchronously, that is your accessing result before its defined (actually in your code example its not undefined, its an empty array) though I expect thats because you had moved the declaration from its original position trying to figure out what was happening.
Try this modified example:-
$.Model.extend('Article',
{
findAll : function(params, success, error){
db.transaction(function(tx) {
tx.executeSql('select * from contents', [], function(tx, rs) {
var result = [];
for(var i=0; i<rs.rows.length; i++) {
var row = rs.rows.item(i)
result.push({
id: row['id'],
title: row['title'],
body: row['body']
});
}
success(result);
});
});
}
});
Article.findAll({}, function(result) {
// process result here
});
Article.findAll() is now an asynchronous function, and its callback (closure) receives the results.
Upvotes: 0
Reputation: 1454
I had the same problem, especially on mobile development projects. I created a library that eliminates the need for callbacks: http://code.google.com/p/proto-q/
This made my code easier to troubleshoot, maintain, and enhance.
I added support for AJAX, web workers, script injection, and the storage APIs. I hope it helps.
Upvotes: 0
Reputation: 15107
I have the same issues, but you might want to use this little wrapper library that makes life easier ;)
http://github.com/grosser/arjs
Upvotes: 0
Reputation: 944
The W3C web database spec talks about support for both Asynchronous and Synchronous database operations. (See 4.3 and 4.4)
If you can't use a synchronous implementation, then you might want to consider approaching the problem like this instead:
$.Model.extend('Article',
{
findAll : function(params, success, error){
var result = []
db.transaction(function(tx) {
tx.executeSql('select * from contents', [],function(tx, rs) {
for(var i=0; i<rs.rows.length; i++) {
var row = rs.rows.item(i)
result[i] = {
id: row['id'],
title: row['title'],
body: row['body']
}
}
success(result); //toss the result into the 'success' callback
})
})
//here result is undefined
alert(result)
return result
}
})
Article.findAll([], function(view) {
//...
}, function() {
//error occured
});
Upvotes: 5