Search code examples
angularjscordovaonsen-ui

angularjs load sequence is not constant


I am currently trying to accomplish following using the angularjs in cordova mobile app (Onsen.UI framework):

  1. open app/page
  2. draw map
  3. connect to SQLdatabase
  4. get markers from DB
  5. Load markers into Vector layer on map

There is a rule that the connection to database could not be done before 'deviceready' event. Therefore my approach was - loading map first, then appending all markers on top existing map. This approach worked just fine because 'map' page is opened by default in application. If for example, i open an app, then move to other page and then go back to 'map' page, then the sequence of loading functions is different and my logic breaks.. Here is the example of what I mean:

fist load (app open)
==========
// module init
var app = angular.module('app', ['onsen', 'ngCordova'])
.run(function($rootScope, $location, $cordovaSQLite){
    ons.ready(function() {
        //// loaded 2   
    }
}
// controller init
app.controller('MapController', function ($scope, $timeout, $http, $cordovaSQLite, $cordovaFile, $cordovaFileTransfer, $cordovaZip, myService)
    ons.ready(function () {
        //// loaded 3

        // connect SQLlite database - OK
        // add markers to map object from SQL - OK
    }

    map init
    {
        //// loaded 1
        //MAP object loaded
    }
}

navigate to some page in menu, go back to page 1

second load
==========
// module init
var app = angular.module('app', ['onsen', 'ngCordova'])
.run(function($rootScope, $location, $cordovaSQLite){
    ons.ready(function() {
        //// not loaded 
    }
}
// controller init
app.controller('MapController', function ($scope, $timeout, $http, $cordovaSQLite, $cordovaFile, $cordovaFileTransfer, $cordovaZip, myService)
    ons.ready(function () {
        //// loaded 1

        // connect SQLlite database - OK
        // add markers to map object from SQL - Failure!!! Map object is not loaded yet! In fact - none of the functions are loaded yet so I cant reference to any of the code next!!
    }

    map init
    {
        //// nothing is loaded because my code breaks at previous step
    }
}

I am just trying to understand why sequence is changing depending on the scenario? Is it possible to make it happen always as in scenario 1.?

The second question would be - what is the approapriate way of loading markers into map from SQL? When should it happen?

  • markers cant be loaded from mapInit block because there is no connection to databse yet!
  • markers can't be loaded in ons.ready block because in case nr. 2 map object is not loaded yet
  • my map object creation depends on functions so I do not want to integrate map initialization into ons.ready block and make it hell a lot more complex

Solution

  • Can you not use promises on your map object creation function to ensure everything is in the correct state before you try and add markers to the map. https://docs.angularjs.org/api/ng/service/$q

    You'll need to dependency inject $q into your controller.

    function initMap(){
        var deferred = $q.defer();
        // init the map - call some functions
        generateAMapObject(function(){
            deferred.resolve(mapObject);
        })
    
        return deferred.promise;
    }
    

    Then inside your ons.ready() function you could do something like

    initMap.then(function(mapObject){
        // add your markers to the map object. You know it has been initialised.
    }