Below is an example that loads a configuration file before bootstrapping the application.
The first call to bootstrap is done to gain access to angular services like $http and $location (you could also inject your own module at this point to access custom services).
After the configuration file has been loaded, angular.bootstrap is called for the main application, with the loaded configuration set as a constant on a makeshift module(rsacAppBootstrap) that is injected.
Here are at least two advantages over using a promise set from a run block:
- Reduced boilerplate of promise for everything dependent on configuration
- Ability to conditionally load dependencies based on the environment using RequireJS
Custom bootstrap script:
angular.bootstrap().invoke(function ($http, $location) {
var env = $location.search()._env || null;
if (env === true) {
env = null;
}
var configUri = 'config/env.json';
if (env) {
configUri = configUri.replace('json', env + '.json');
}
var rsacAppBootstrap = angular.module('rsacAppBootstrap', [])
.run(function ($rootScope, $location, $window) {
var env = $location.search()._env;
$rootScope.$on('$locationChangeSuccess', function () {
var newEnv = $location.search()._env;
if (env !== newEnv) {
$window.location.reload();
}
})
});
function bootstrap(config) {
rsacAppBootstrap.constant('rsacConfig', config || {});
angular.element(document).ready(function () {
var modules = ['rsacApp', 'rsacAppBootstrap'];
if (config.modules){
config.modules.forEach(function(v){
modules.push(v);
})
}
angular.bootstrap(document, modules);
});
}
$http.get(configUri)
.success(function (config) {
config._env = env;
if (config.require) {
require(config.require, function(){
bootstrap(config);
});
} else {
bootstrap(config);
}
})
.error(function () {
bootstrap();
});
});
Example configuration file:
{
"_meta": [
"Development environment settings"
],
"require":[
"//code.angularjs.org/1.2.3/angular-mocks.js",
"components/rsacMock/js/rsacMock.js"
],
"modules":[
"ngMockE2E",
"rsacMock"
],
"resources": { ... }
}