0

i have the following piece of javascript where i perform an sql query, and depending on the result i need to perform a second query. Although i manage using a closure to iterate proper values for the second query, i haven't been able to return the desired value back. I keep getting undefined.

        db.transaction(function(tx) {
            tx.executeSql('SELECT * FROM maintainance', [], function(tx, results){
                maintainance_length = results.rows.length;
                maintanance_query = results.rows;
                for (i = 0; i < maintanaince_length; i++) {
                    maintainance_title = maintanance_query[i].element;
                    var classAction = function(){
                        if(maintanance_query[i].code == '0'){
                            return 'no';
                        }else{
//over here i use the closure to iterate each seperate maintainance_title value
                            (function(maintainance_title){
                            db.transaction(function(tx) {
                            tx.executeSql('SELECT * from maintainance_history WHERE element = \''+maintainance_title+'\'',
                            [], function(tx, results){
                                if(results.rows.length > 0 && results.rows[0].action == '1'){
                                    return 'ok';
                                }else{
                                    return 'warn';
                                }
                            },function(tx, error){
                                    console.log(error);
                                    console.log(tx);
                            });});
                            })(maintainance_title);
                        }
                    }
                    historyIcon = "<div class=\""+classAction()+"\"></div>";
                }
                },function(tx, error){

                }
            );
         }); 

i have tested a few variations ovr ths code, but still the result would either be "undefined" of uncaught exception that classAction is not a function

nikolas
  • 723
  • 2
  • 17
  • 37
  • 1
    `classAction()` is an asynchronous function and you are trying to call it synchronously. Unfortunately, the places where you return `'ok'` or `'warn`' return into emptiness, nothing is really done with those return values. There is no `return` at the bottom of `classAction()` either, so it will always return undefined. – aaronofleonard Apr 27 '16 at 22:07
  • so, instead i could wrap "historyIcon = "
    ";" into a function, and call it where each return takes place. In this way, it will be called when each iteration was completed
    – nikolas Apr 27 '16 at 22:14
  • Yea man, that's the approach I took in my answer, good thought ;) – aaronofleonard Apr 27 '16 at 22:16

1 Answers1

1

Going along with my comment, since classAction is asynchronous, we must treat it like an asynchronous function. This means that return goes out the window! We could use Promises, but that would require a much more significant rewrite. Here is my proposed simpler rewrite using callbacks. This still might not work, depending on what you want to do with historyIcon. But historyIcon will be set to the appropriate value, and if you need to handle it, another callback may be in order.

db.transaction(function(tx) {
    tx.executeSql('SELECT * FROM maintainance', [], function(tx, results){
        maintainance_length = results.rows.length;
        maintanance_query = results.rows;

        for (i = 0; i < maintanaince_length; i++) {
            maintainance_title = maintanance_query[i].element;

            var classAction = function(callback){
                if(maintanance_query[i].code == '0'){
                    callback('no');
                }
                else {
                    (function(maintainance_title){

                        db.transaction(function(tx) {
                            tx.executeSql('SELECT * from maintainance_history WHERE element = \''+maintainance_title+'\'', [],
                                function(tx, results){
                                    if(results.rows.length > 0 && results.rows[0].action == '1'){
                                        callback('ok')
                                    }else{
                                        callback('warn');
                                    }
                                },function(tx, error){
                                        console.log(error);
                                        console.log(tx);
                                });
                        });

                    })(maintainance_title);
                }
            };

            classAction(function(action) {
                historyIcon = "<div class=\""+action+"\"></div>";
            });
        }
    },function(tx, error){
        // error stuff
    });
 }); 
aaronofleonard
  • 2,546
  • 17
  • 23
  • now got more complicated, due to the delay in the asynchronus call, only the historyIcons that have action no append to the dom, and not the rest, due to the delay – nikolas Apr 27 '16 at 22:48
  • 1
    @nikolas, well, you need to modifying the function that manipulates the DOM to work asynchronously also. You inherently cannot use the results of asynchronous calls in a synchronous contex – aaronofleonard Apr 28 '16 at 17:47
  • that's true, i added an if statement in the call back and inserted all necessary items in the dom when the total expected callbacks occured :) – nikolas May 03 '16 at 12:50