Announcement
If possible, we recommend utilizing the technique outlined in the "Asynchronously Bootstrapping AngularJS Applications with Server-Side Data" article for improved performance.
You now have the option to utilize the angular-deferred-bootstrap module!
This answer's validity may be questioned. While you can still reference the concepts discussed here, we advise thorough testing with your specific code. We will strive to keep this answer current with the latest technologies.
Previous Answer
There are multiple strategies available for handling asynchronous application initialization.
For instance, when dealing with data that must be resolved prior to any controller execution, leveraging the `resolve` option within `ngRoute`'s `$routeProvider` is straightforward. However, if you require global data to load before any controller activation, alternative methods are necessary.
In this response, I aim to compile various solutions in order of preference.
1. Utilizing ui-router
By opting for ui-router instead of native `ngRoute`, establishing an abstract root state to resolve all data beforehand, prior to sub-state activation, becomes feasible.
We strongly endorse this approach due to the advanced features offered by `ui-router`, including hierarchical resolution of dependencies and widespread developer acceptance.
Sample
module.config(function($urlRouterProvider, stateHelperProvider) {
$urlRouterProvider.otherwise('/404');
stateHelperProvider.setNestedState({
name: 'root',
template: '<ui-view/>',
abstract: true,
resolve: {
user: function(UserService) {
// Resolving promise from getCurrentUser() before nested states activate.
return UserService.getCurrentUser();
}
},
children: [{
name: 'index',
url: '/',
templateUrl: '/partials/index'
},
...
});
});
The stateHelper
simplifies implementation using abstract root scope.
Since the abstract root scope lacks direct activation possibilities and lacks a URL, template: '<ui-view/>'
is essential for correct rendering of nested views.
2. Creating Promises in Root Controller
One approach involves generating promises within the root controller, specifically in the `run()` function, and adding them to `$rootScope`.
A demonstration Plunk is available:
http://plnkr.co/edit/gpguG5Y2S4KOz1KOKzXe?p=preview
Although effective, this method increases code complexity and readability challenges (callback hell). We suggest recourse to this only if the primary approach proves inadequate.
3. Embedding Data within Application Page
An alternative involves directly incorporating initialization data into the generated HTML page on the server for subsequent access within your application.
Consider the following example:
<html>
...
<script type="text/javascript">
application.init({
userData: { ... }
});
</script>
...
Subsequently, manually bootstrap the AngularJS application within the `init()` method of your custom `application` object.
While functional, this method raises concerns regarding the separation of frontend and backend components in web applications. Ideally, frontend should comprise static content deliverable via CDN, while backend operates solely as an API without presentation elements. Nonetheless, if integrated components are acceptable, this approach remains viable.