sagarpdesai
sagarpdesai

Reputation: 193

Ionic ngCordova SQLite execute method - control should return after 'then' is called

I am having a function 'insertAllLinksFunc'-it inserts data in database. When the execute method is called inside 'insertAllLinksFunc', the control returns before 'then' method completes. I want the control to return only after the 'then' method has completed.

Here's the log:

            8     697189   log      test : inside test              
            9     697193   log      insertAllLinksFunc : inside insertAllLinks : arr length=1               
            10    697195   log      insertAllLinksFunc : ret=               
            11    697196   log      test : arr0=                
            12    697197   log      test : exitting test                
            13    697206   log      insertAllLinksFunc : item=LinkEntity[linkId=1443150697190, title=title-1443150697190, imgPath=imgPath-1443150697190]

What I want is code at log 13 should be executed between code at log 9 and log 10

Code:

myController.js

            var db=null;
            var myModule = angular.module('MyController', ['ionic', 'ngCordova'])
            .run(function($ionicPlatform, $cordovaSQLite) {
              $ionicPlatform.ready(function() {
                console.log('inside onReady');
                db = $cordovaSQLite.openDB("my.db");

                $cordovaSQLite.execute(db, "create table if not exists POSTS_TBL( POST_ID numeric primary key , CREATE_DT text not null, POST_TYPE text not null, TH_LOCAL_IMG_PATH text , TH_SERVER_IMG_PATH text , LINK_URL text , TITLE text , CAPTION text , MESSAGE text , DESCRIPTION text , LOCAL_IMG_PATH text , SERVER_IMG_PATH text , POST_JSON text not null)");
                console.log('exitting onReady, db='+db);
              });
            })

            .factory('queryFactory', function($cordovaSQLite){

insertAllLinksFunc = function(arr){
    console.log('insertAllLinksFunc : inside insertAllLinks : arr length='+arr.length);
    var ret = null;
    if(arr.length>0){
        var query = "INSERT INTO POSTS_TBL (POST_ID, TITLE, CAPTION, POST_JSON, DESCRIPTION, MESSAGE, SERVER_IMG_PATH, LINK_URL, CREATE_DT, POST_TYPE) VALUES (?,?,?,?,?,?,?,?,?,?)";

        var ret = [];
        for(item in arr){
            console.log('insertAllLinksFunc : item='+arr[item].toString());
            $cordovaSQLite.execute(db, query, [arr[item].linkId, arr[item].title, arr[item].caption, arr[item].linkJSON, arr[item].description, arr[item].msg, arr[item].serverPath, arr[item].url, arr[item].createDt, Settings.POST_TYPE_LINK]).then(function(res) {
            console.log("insertAllLinksFunc : insertAllLinksFunc : INSERT ID -> " + res.insertId);
            ret.push(res);
            }, function (err) {
                console.error(err);
                return -1;
            });

        }
        console.log('insertAllLinksFunc : ret=' + ret);
        return ret;
    }
}
            return {
                insertAllLinks : insertAllLinksFunc
            }})

app.js

            angular.module('starter', ['ionic', 'ngCordova', 'MyController'])
            .controller('myCtrl', function($scope, queryFactory){
              $scope.test = function(){
                console.log('test : inside test');    
                var time = new Date().getTime();
                var entity = new LinkEntity(time, 'title-'+time, 'imgPath-'+time, 'serverPath'+time, '{}', 'url', 'caption', 'description', time, 'msg');
                var arr = [entity];
                var arr0 = queryFactory.insertAllLinks(arr);
                console.log('test : arr0='+arr0);
                console.log('test : exitting test');
              }  
            });

entities.js

            function LinkEntity(linkId, title, imgPath, serverPath, linkJSON, url, caption, description, createDt, msg){
                this.linkId = linkId;
                this.title = title;
                this.imgPath = imgPath;
                this.serverPath = serverPath;
                this.linkJSON = linkJSON;
                this.url = url;
                this.caption = caption;
                this.description = description;
                this.createDt = createDt;
                this.msg = msg;
            }

            LinkEntity.prototype.toString = function(){
                return 'LinkEntity[linkId='+ this.linkId +', title='+this.title+', imgPath='+this.imgPath+']';
            }

Upvotes: 0

Views: 347

Answers (1)

JSNorth
JSNorth

Reputation: 46

The sql lite function $cordovaSQLite.execute is an assynchronous function. That means while the function is called and the data is inserted the app works on. If the data has been inserted the functions in ".then()" are called. So all the code in .then() is called later and your app has allready been writing the lines 9 & 10.

For understanding the problem you have to take a look at: AngularJS $q and promises.

In your case you have the problem of working with more than one promise. For that you could collect the promises in an array and work with $q.all: combining promises or stackoverflow: how-to-chain-multiple-promises-within-and-after-a-for-loop. But I would assume if you understand how to work with $q and promises you will get the main problem.

Upvotes: 1

Related Questions