-1

I want to return data that comes from a sqlite query in javascript. The problem is as follows:

        App.dbInstantion.transaction(function(tx){
                tx.executeSql('SELECT * FROM footsteps', [],
                    function(tx, results) {
                        for (var i = 0; i < results.rows.length; i++) {
                                 footsteps.push(results.rows.item(i));
                             }
                            //WRONG RETURN SCOPE
                            return footsteps;

                    }, self.errorCB
                );
            }, self.errorCB);

            //FOOTSTEPS IS NOT FILLED YET SO AN EMPTY ARRAY IS RETURNED
            return footsteps;

I tried to use $.Deferred but that did not solve the problem. Does anyone have a suggestion for this?

Greetz,

flavian
  • 28,161
  • 11
  • 65
  • 105
Sjaak Rusma
  • 1,424
  • 3
  • 23
  • 36
  • Have a look at [How to return the response from an AJAX call?](http://stackoverflow.com/q/14220321/218196). Even though it's not Ajax, the solutions are the same. If deferred objects/promises didn't work for you, you used them wrongly. – Felix Kling May 12 '13 at 11:04

3 Answers3

1

Well I would say the approach is wrong.

Returning data does not make sense here. Probably what you would like to do is handing over "footsteps" to the outer function. However, by the time the inner function does execute, the outer did already finish. Whatever you want to do with footsteps, you have to do it from the inner function. Even though the outher function did already finish, you still have access to all the variables, that were defined in context of the outer function. Maybe this helps.

Read about callbacks and closure. Content I can recommend is "JavaScript Patterns" from O'Reilly or any content from Douglas Crockford.

Daniel
  • 2,343
  • 2
  • 20
  • 24
0

You can actually use deferred objects. Create the deferred object and have the interested code listen to it. Then, do the operation. Once the operation finishes, resolve the deferred object, passing it the data. All listeners to that deferred will receive the data during the resolve.

Joseph
  • 117,725
  • 30
  • 181
  • 234
0

This is how I figured it out:

First the function itself, it accepts a callback which I will pas tot the .then of the Defferred:

functionName: function(callback, param1, param2) {
            var self = this;
        var data = function getData(){
            var dfd = $.Deferred();
            App.dbInstantion.transaction(function(tx){
                tx.executeSql('SELECT * FROM blabla',
                    [], dfd.resolve, self.errorCB
                );
            }, self.errorCB);

            return dfd.promise();
        }

        //return deferred is done(.then) function with the sent callback to this function
        return data().then(callback);
    },

Then I use it like this:

initialize: function() {
          functionName(this.passedCallback);
},


 passedCallback: function(tx, results) {
// I got the results of the query here!
                    window.footsteps = [];

                for (var i = 0; i < results.rows.length; i++) {
                    window.footsteps.push(results.rows.item(i));
                }

                //trigger backbone custom event to deal with async problems
                App.Vent.trigger('retrievingFootsteps:done');
            },
Sjaak Rusma
  • 1,424
  • 3
  • 23
  • 36