27

I really need some data to be loaded before bootstrapping angular. For this reason I've created a run block/ Within this run block I call a method on a service which load some data from the server. Since this is a async call, JavaScript gets further with execution, which results in some undefined objects in my app.

I am working with routes, but it is not an option to work with the resolve property.

Could someone provide a solution on how to wait for a promise to be ready in the run block?

EDIT:

Thanks to the given answers, I have solved it by manually bootstrapping angular:

$(document).ready(function () {
    $.ajax('/Data/GetDropdownData', {type:'POST'}).done(function (response) {
        app.run(['ListService',  function (ListService) {
            ListService.setData(response);
        }])

        angular.bootstrap(document, ["sma"]);
    })
})
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Martijn
  • 24,441
  • 60
  • 174
  • 261
  • promise.then(function(data){ $rootScope.data = data; }); but I think it's too easy ^^ and you are not sure to have it ready in your controller – Whisher Feb 11 '14 at 09:29
  • @Whisher Thanks for the reply, but this is indeed not an option. I really need the data to be loaded before starting up the app. – Martijn Feb 11 '14 at 09:33
  • So maybe manual bootstraping would be an option http://docs.angularjs.org/guide/bootstrap – Fedor Skrynnikov Feb 11 '14 at 09:38
  • yep, as @FedorSkrynnikov said, manual bootstrap is the way I would go – doodeec Feb 11 '14 at 09:43
  • @FedorSkrynnikov: Thanks for the comment, but where do I place the code for loading my data? – Martijn Feb 11 '14 at 09:48
  • I added answer and put comment regarding place there – Fedor Skrynnikov Feb 11 '14 at 09:54

4 Answers4

5

You may want to look at this SO question - it shows how to initialize an AngularJS service with asynchronous data.

Here is a plunkr example from that question showing the use of AngularJS services like $http to load the configuration and then do further initialization.

This answer has a great explanation and shows an example of waiting for the DOM to load like this (plunkr example from that answer is here) :

angular.element(document).ready(function() {
  angular.bootstrap(document);
});
Community
  • 1
  • 1
SnapShot
  • 5,464
  • 5
  • 42
  • 40
4

As I commented would put it here

You may try manual bootstrap

<script> 
   angular.element(document).ready(function() {
      angular.bootstrap(document); 
   });
</script>

Of cause in this case you cannot use controllers and angular way of getting data. I think you would have to load your data by jQuery, bootstrap your angular in jquery callback and then init your scope variable with data you got from jquery.

Fedor Skrynnikov
  • 5,521
  • 4
  • 28
  • 32
2

I guess that the only solution is manually bootstrap your application. Maybe you can find some help in this question Delay Angular App Initialization and in this small article Manually bootstrapping AngularJS for asynchronous loading in Internet Explorer.

As stated in the previous article, to do a manual bootstrap:

angular.element(document).ready(function() {
  angular.bootstrap(document, ["myApp"]);
});

Be sure to remove all the refences of ng-app in your HTML to stop the auto bootstrapping.

Community
  • 1
  • 1
Atropo
  • 12,231
  • 6
  • 49
  • 62
0

an other solution since I would not ommit parts of my application but I still have to wait for things to be loaded.

the bootstrap directive (not affiliated to twitter bootstrap) :

myApp.directive('myBootstrap', function() {
  return {
    scope: {
      promise: '=myBootstrap'
    },
    template: '<div ng-if="ctrl.isReady" ng-transclude></div>',
    controllerAs: "ctrl",
    transclude: true,
    controller: function($scope) {
      var ctrl = this;
      ctrl.isReady = false;

      //else an array of promises can be filled by a service
      $scope.promise.then(function() {
          ctrl.isReady = true;
      });
    }
  };
});

and the related plnkr : http://plnkr.co/edit/vx4aWS?p=preview

DEY
  • 1,770
  • 2
  • 16
  • 14