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
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
});
I have the same issues, but you might want to use this little wrapper library that makes life easier ;)
http://github.com/grosser/arjs
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.
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.