1

First I know WebKit do not allow Make synchronous requests to SQLite database. And I'm start playing with it and tried to assign result to global variable "data". I still not sure if it's possible but want to ask you.

  1. I'm created global object to store respond from DB

    var data = {};
  2. Here is DB class


var db = {
        mydb: false,
        init: function () {
            try { 
                if (!window.openDatabase) { 
                    alert('not supported'); 
                } else { 
                    this.mydb = openDatabase('test_db', '1.0', 'Test DB', 1024*1024*5); 
                }
            } catch(e) { 
                // Error handling code goes here. 
                if (e == INVALID_STATE_ERR) { 
                    // Version number mismatch. 
                    alert('Invalid database version.'); 
                } else { 
                    alert('Unknown error '+e+'.'); 
                } 
                return; 
            }
        },
        exec: function (query, params) {
            try {
                this.mydb.transaction(function(transaction) {
                    transaction.executeSql(query, params, db.dataHandler, db.errorHandler);
                });
            } catch(e) {
                alert(e.message);
            }
        },
        dataHandler: function (transaction, results) {
            // Handle the results
            data = results.rows;
            return true;    
        },
        errorHandler: function (transaction, error) {
            // returns true to rollback the transaction
            alert('Code: '+error.code+'\nMessage: '+error.message);
            return true;
        },
    }
  1. And finally here is the problem:

$(function () {
    db.init();
    db.exec('SELECT * FROM errors;');
    alert(Log.object_toString(data) ); // this alert show empty object as I declared in first line 
    alert(Log.object_toString(data) ); // this one return object with responded data from database
});

So the problem is I can't manipulate with "data" right after db.exec() call, but if I make alert() after transaction then data will populate with all information.

Any ideas how can I avoid it?

2 Answers 2

3

I would assume that you're making an asynchronous AJAX call, so your alert() fires before the response is received.

EDIT: As @Nick noted, this is not AJAX, but is an issue with it being asynchronous.

I don't know anything about the API you're using, but it would seem as though your alerts should be inside the dataHandler method:

dataHandler: function (transaction, results) {
    // Handle the results
    data = results.rows;
    alert(Log.object_toString(data) ); 
    alert(Log.object_toString(data) );
    return true;    
},

Or should be in some other function that is called from inside dataHandler.

dataHandler: function (transaction, results) {
    // Handle the results
    data = results.rows;
    someFunction( data );
    return true;    
},

// ...

function someFunction( data ) {
    alert(Log.object_toString(data) ); 
    alert(Log.object_toString(data) );
}

The reason an alert() in between makes it work, is that the pause gives the response a chance to return before the other alerts run.

Sign up to request clarification or add additional context in comments.

8 Comments

This is HTML5, no AJAX involved, but it is asynchronous :)
Thanks @Nick. Was a shot in the dark. I've really got to get up to speed on HTML5. :o)
It looks like he's using a local database. Not that it matters, it's still asynchronous. I think exec should accept a callback function parameter which it passes on to its subordinate functions. Edit: Nick beat me to it :p
@Bart - it does accept one, that's the db.dataHandler part of the .exec() signature :)
But the db object's exec does not support it atm.
|
1

The problem is that if you access data right after you called exec the dataHandler callback wasn't called yet. The only way to make sure that you actually received your data from the query is to handle it within the callback itself. For that you could redesign your class a bit to allow the exec function to actually also take a callback function that will be called as soon as the query was executed successfully, eg

exec: function (query, params, onSuccess /*, onFailure*/) {
    try {
        var onFailure = arguments[3] || function(){};
        this.mydb.transaction(function(transaction) {
             transaction.executeSql(query, params, onSuccess, onFailure);
        });
    } catch(e) {
        onFailure(e);
    }
}

Then you can call your db.exec like this:

db.exec('SELECT * FROM erros;', null, function(rows) {
    alert(Log.object_toString(rows));
}, function() {
    var error = arguments[0] || {message: 'Unknown Exception'};
    alert('An error occured: ' + error.message);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.