0

with reference to this answer How do I return the response from an asynchronous call? how could i implement this one in my secanrio.

I am trying to do caching with use of sqlite using cordova sqlite plugin but my problem is my controller executes before my factory completes its execution. I am pasting my controller code and my factory code. I had put alert for knowing the sequence of execution. My ideal alert sequence is 1,2,3,4,5,6 but when i am executing the code i am getting alert sequence like 1,5,6,2,3,4. I am pasting my controller and factory code below.

angular.module('foo').controller('PriceListController',["$scope","$http","$stateParams","CURD","$q","DB", function($scope,$http,$stateParams,CURD,$q,DB) {

$scope.brand_id=Number($stateParams.id);
$scope.process=true;
$scope.pricelists=[];    
$scope.getBrandDocs= function(){
    var parameters=new Array(2);
    parameters[0]=$scope.brand_id
    parameters[1]=1;
    CURD.exc_query("select * from brand_docs where brand_id=? AND type=?",parameters)
        .then(function(price_lists) {
            alert("2");
            $scope.inter_pricelist=price_lists;
            console.log("Records from query call:"+JSON.stringify( $scope.inter_pricelist)); 

            $scope.deferred = $q.defer();    
            if ($scope.inter_pricelist){
                console.log("Found data inside cache", JSON.stringify($scope.inter_pricelist));
                $scope.deferred.resolve($scope.inter_pricelist);
                // alert(JSON.stringify( $scope.inter_pricelist));
                alert("3");

            } 
            else{
                $http.get('http://foo.com?brand='+ $scope.brand_id +'&type=price_list')
                .success(function(data) {
                    //alert("http call");
                    console.log("Received data via HTTP",JSON.stringify(data));
                    angular.forEach(data.data.info, function(value, key) {
                        var sql = "INSERT OR REPLACE INTO brand_docs(id, brand_id, name, file_url,type) VALUES (?, ?, ?, ?, ?)"; 
                        var parameters=new Array(5);
                        parameters[0]=value.id;
                        parameters[1]=value.brand_id;
                        parameters[2]=value.name;
                        parameters[3]=value.file_url;
                        parameters[4]=value.type;    
                        var result=DB.query(sql,parameters);
                    });

                    $scope.deferred.resolve(data.data.info);

                })
                .error(function() {
                    console.log("Error while making HTTP call.");
                    $scope.deferred.reject();
                });
        }

        return ($scope.deferred.promise).then(function(pricelists){
        alert("4");    
            return pricelists;
        },function(){});

    },function(){});  
  alert("5");  
};

$scope.pricelists=$scope.getBrandDocs();
alert("6"); 
}]);

// This is factory code i am pasting

angular.module('foo').factory('DB', function($q, DB_CONFIG,$cordovaSQLite) {
    var self = this;
    self.db = null;

    self.init = function() {
        try{ 
            self.db =  window.sqlitePlugin.openDatabase(DB_CONFIG.name, '1.0', 'database', -1);
            angular.forEach(DB_CONFIG.tables, function(table) {
                var columns = [];
                angular.forEach(table.columns, function(column) {
                    columns.push(column.name + ' ' + column.type);
                });
                var query = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
                self.query(query);
                console.log('Table ' + table.name + ' initialized');
            });
        }
        catch(err){
        }

    };

    self.query = function(query, bindings) {
        bindings = typeof bindings !== 'undefined' ? bindings : [];
        console.log("Query:"+query+" bindings:"+ bindings);
        var deferred = $q.defer();

        self.db.transaction(function(transaction) {
            transaction.executeSql(query, bindings, function(transaction, result) {
                console.log("Query sucessfull :"+ query);
                console.log("Result of Query:"+ JSON.stringify(result));
                deferred.resolve(result);

            }, function(transaction, error) {
                console.log("Error:"+ JSON.stringify(error));
                deferred.reject(error);
            });
        });

        return deferred.promise;
    };

    self.fetchAll = function(result) {
        var output = [];

        for (var i = 0; i < result.rows.length; i++) {
            output.push(result.rows.item(i));

        }
         //console.log("RECORDS:" +JSON.stringify(output));
        return output;
    };

    self.fetch = function(result) {
        return result.rows.item(0);
    };

    return self;
})
.factory('CURD', function(DB) {
    var self = this;

    self.all = function(table_name) {
        return DB.query('SELECT * FROM '+table_name)
        .then(function(result){
            return DB.fetchAll(result);
        });
    };

    self.exc_query = function(query,parameters) {
        return DB.query(query,parameters)
        .then(function(result){
            return DB.fetchAll(result);
        });
    };

    self.getById = function(id,table_name) {
        return DB.query('SELECT * FROM '+table_name +' WHERE id = ?', [id])
        .then(function(result){
            return DB.fetch(result);
        });
    };

    return self;
});
Community
  • 1
  • 1
Hamza Dairywala
  • 482
  • 2
  • 11
  • with reference to this answer How to return the response from an asynchronous call? how could i implement this one in my secanrio. – Hamza Dairywala Nov 08 '15 at 07:36

1 Answers1

0

The query completes asynchronously. By that I mean that when you call CURD.exec_query(), the query is queued and as soon as it is queued, your method continues to execute at "return ($scope.deferred.promise).then(function(pricelists){". That's why 4, 5, 6 show up before 2 and 3. Once the query completes, again, asynchronously, the ".then()" method is called, which is when 2 and 3 are alerted.

Note that getBrandDocs() is going to return BEFORE then .then() method is called. What you could do is have your .then() method emit an event that is asynchronously picked up in the calling code which would in turn execute the 4, 5, and 6 steps.

TJDJD
  • 70
  • 5
  • Brother can you please explain it in detail or show me the example what i need to do – Hamza Dairywala Nov 07 '15 at 08:02
  • Brother can you please explain it in detail or show me the example what i need to do my need is to get the pricelist store in $scope.pricelists its either from cache or from http . Thats why i am calling $scope.pricelists=$scope.getBrandDocs(); but every time i am getting $scope.pricelists = undefined – Hamza Dairywala Nov 07 '15 at 08:10