Manual Bootstrap Angular With Http Calls
Solution 1:
You can use $http
outside of your angular module with angular.injector
. With $http
you can request the config from your server and bootstrap your app when $http's promise resolves.
Create module
var app = angular.module("app", []);
app.provider("configService", function () {
var configService = {
config: {}
};
this.setConfig = function (config) { configService.config = config; };
this.$get = function() { return configService; };
});
Function that fetches config from server
functionfetchConfig() {
var$http = angular.injector(["ng"]).get("$http");
return$http.get("http://www.google.com");
}
Function that bootstraps app
functionbootstrap(config) {
app.config(["configServiceProvider", function (configServiceProvider) {
configServiceProvider.setConfig(config);
}]).run(["configService", function (configService) {
//Not necessary, just to confirm everything workedconsole.log("YAY! You have a config:", configService.config);
}]);
angular.bootstrap(document, ["app"])
}
Put it all together!
fetchConfig().then(
/*sucess*/function (config) { angular.element(document).ready(function () { bootstrap(config); }); },
/*fail*/function (err) { console.log("UH OH could not retrieve config!", err); });
Solution 2:
EDIT: Please use @StevenWexler 's answer: https://stackoverflow.com/a/37599857/5670592. It is much more correct, uses a nifty angular feature ($inject), and will provide configuration before the beginning of the bootstrap cycle.
I have updated the application with your constraints regarding blocking execution until API call is complete.
Try this: https://jsfiddle.net/6svnemu8/3/
I moved the code to the module.run(...) block. This is where all providers are available and you can use $http and your ConfigService. I kept the bootstrap call in the document ready function, and I also added the $q service so you can block execution of the application until the API call is complete. You can verify this by looking at the order of the test outputs in the console:
angular.module('app').run([
'ConfigService', '$http', '$q',
function(configService, $http, $q) {
console.log('test 2');
var deferred = $q.defer();
$http.get('/6svnemu8/2/').then(function(result) {
deferred.resolve(result);
}, function(result){
deferred.reject(result);
});
console.log("test 3");
deferred.promise.then(function(result){
console.log('wierd wierd');
configService.config(result);
}, function(result){
console.log("call failed.");
});
}
]);
Solution 3:
Option 1 -- if you have an MVC app
In your main razor view, use JSON.Net to serialize your Model (or a property on it) to JavaScript.
<script>window.configuration = @(Html.Raw(JsonConvert.SerializeObject(Model)))
</script>
Then put it into an angular constant so you can inject it anywhere you need it, and it's guaranteed to be there. This is the most convenient way to do it.
angular.module('YourModule').constant('configuration', window.configuration);
Option 2 -- loading it asynchronously
This service will load the configuration and cache the promise.
angular.module('YourModule').factory('configuration', ['$http', function($http) {
var configurationLoaded;
var service = {
get: get
};
function get() {
if(configurationLoaded) return configurationLoaded;
configurationLoaded = $http.get( ... );
return configurationLoaded;
}
return service;
}]);
Then anywhere you need it, you'll have to pull out properties from it like this:
angular.module('YourModule').controller('SomeController', ['configuration', function(configuration) {
var vm = this;
configuration.get().then(function(config) {
vm.someSetting = config.someSetting;
});
}]);
Post a Comment for "Manual Bootstrap Angular With Http Calls"