When are the angular controller's loaded?


#1

I was wondering if the angular controllers are loaded before or after the “deviceready” event fired off by Cordova. I did a test by putting a

console.log("App ctrl loaded");

Inside of my most parent AppCtrl, and then

document.addEventListener('deviceready', function() {
    console.log("Device ready");
});

Right before the end body tag of the HTML.

In my device’s system log using the console plugin. I got the “Device Ready” log, but no “App Ctrl Loaded”. I assumed then that the controllers are loaded before cordova is actually ready. Is this assumption correct?


$localStorage can't be loaded in some cells
How to only use Dependencies in Controllers (E.g. NgCordova) when the App is ready?
#2

Hey @seanhill. There isn’t necessarily a connection between controller load time and deviceready firing. That event comes from the Cordova internals, and if you set the listener too late, the event will have already fired and you’ll miss it.

To deal with this, we’ve given you the Platform service, which you can use to always call a function when the device is ready (or after if it’s already been loaded):

controller('MyCtrl', function($scope, Platform) {
  Platform.ready(function() {
    // Platform stuff here.
  });
});

#3
    controller('MyCtrl', function($scope, $ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Platform stuff here.
  });
});

For me…


#4

So, Is it right to write this into a factory?

 $ionicPlatform.ready(function() {
getLocation: function() {
      var q = $q.defer();

      navigator.geolocation.getCurrentPosition(function(position) {
        q.resolve(position);
      }, function(error) {
        q.reject(error);
        console.log("Errore posizione " + error.code + "-" + error.message );
      });
   

      return q.promise;
    }
  });

#5

Hi !

I have to wait for plugins to load in most of my controllers and it’s pretty painful to write

$ionicPlatform.ready(function() {
  // Platform stuff here.
});

for every controller using a plugin (and it could ends with some race conditions…).

Is there a way to globally wait for the ready before loading the angular app ?

Thanks


#6

You have to bootsrap AngularJS by yourself.
First remove the ng-app directive from your index.html. Then attach an event listener to your document ready and deviceready event. After that two events are fired you can bootstrap angular manually:

var ngDocument = angular.element(document);

angular.element(ngDocument).ready(function() {
    ngDocument.on('deviceready', function() {
      var body = ngDocument.find('body');
      angular.bootstrap(body, ['myApp']);
    });
});

var myApp = angular.module('myApp', []);

If you make it like this it is guaranteed that all cordova plugins are loaded before Angular initializes his services, controllers and so on.


#7

You’re right.
But this slows down all your app event if you don’t need plugins…

I opted for a different solution : for each plugin I create a service which is responsible to wait for the ready using promises…


#8

That’s also a good solution :slight_smile:


#9

I do like ngbit, but the following code is reusable and let you try the app in a browser by bootstrapping anyway if cordova is not present.

var CordovaInit = function(appModule) {

    var onDeviceReady = function() {
        receivedEvent('deviceready');
    };

    var receivedEvent = function(event) {
        console.debug('Start event received, bootstrapping application setup.');
        var body = document.getElementsByTagName("body")[0];
        angular.bootstrap(body, [appModule]);
    };

    this.bindEvents = function() {
        document.addEventListener('deviceready', onDeviceReady, false);
    };

    //If cordova is present, wait for it to initialize, otherwise just try to
    //bootstrap the application.
    if (window.cordova !== undefined) {
        console.debug('Cordova found, waiting for device.');
        this.bindEvents();
    } else {
        console.debug('Cordova not found, booting application');
        receivedEvent('manual')
    }
};

Then in your index.html just add:

<script>new CordovaInit('myApp');</script>

I found that on the internet, most likely here: https://gist.github.com/nick-pww/9626837


#10

Hi

can you provide an example how u achieved it?


#11

I’ve been looking for this since morning!
The select queries of sqlite database did not come to the page using ng-init. because the page was loading first did not see the database. I used this code to run the platform ready before the controller so the database was open.