2

I am writing an angular app that will need some asynchronous code to run during the bootstrap phase. Let's say that this pahe includes collecting several AJAX call responses. As the resources are being requested, there is an overlay icon shown (waiting for data). After all of the requests are done, the application is ready to start working. The question is: how to do this correctly in angular?

The things I've found in the web so far seem to be hacky, such as:

I am looking for a convenient and clean solution. In backbone (or anything built on top of it), for example, you may simply run several ajax requests inside initialize method. Backbone relies on jQuery afterall - or something complaint - so just collect them all asynchronously using $.when(list-of-promises) and fire an event that will asynchronously bootstrap the whole app. This is purely modular. And there are no hacks.

0

1 Answer 1

4

You don't need to delay bootstrapping your app.

You use $http service to request data. $http methods return promises. You can use the $q service's $q.all() method to wait until all the $http promises have resolved.

Something similar to this:

<body ng-app="app">
    <div ng-if="!Initialized">
        Overlay (waiting for data)
    </div>
    <div ng-if="Initialized">
        Application
    </div>
</body>


angular.module('app', [])
.run(function($rootScope, $q, $http){
    $rootScope.Initialized = false;
    $q.all({
        firstRequest: $http.get('/someresource'),
        secondRequest: $http.get('/someotherresoruce'),
        thirdRequest: $http.get('/athirdresource')
    }).then(function(results) {
        $rootScope.resource1 = results.firstRequest;
        $rootScope.resource2 = results.secondRequest;
        $rootScope.resource3 = results.thirdRequest;
        $rootScope.Initialized = true;
    });
});

Note, this is to demonstrate how to wait for multiple $http requests concurrently and to change from a "loading" to a "ready" state. Using $rootScope is generally frowned upon as a way to share data across controllers.

Sign up to request clarification or add additional context in comments.

3 Comments

I think this answer provides the simplest and most Angular way of accomplishing this. If you really really need to delay initialization, you can provide a set of dependencies for your controller when you define your routes. Note this applies to the controller and not the overall app bootstrap. Take a look at the resolve property for the route parameter: docs.angularjs.org/api/ngRoute/provider/$routeProvider
@JoeEnzminger can you tell more about Using $rootScope is generally frowned upon as a way to share data across controllers? I don't want to follow bad practice - is there a better way of doing this?
Generally you want to encapsulate shared data in angular services. Items on $rootScope are global, which makes implementing controllers that depend on $rootScope data difficult to unit test. For services that need to be initialized, the service can have an init() method that returns a promise that is resolved when the service is ready, and you can use that promise in the same way you use the promise returned by $http in my example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.