AngularJS load config on app start

Angularjs

Angularjs Problem Overview


I need to load a config file (JSON format) upon my AngularJS app startup in order to load few parameters which will be used in all api calls. So I was wondering if it is possible to do so in AngularJS and if yes where / when I shall be loading the config file?

Note:

  • I will need to save the config file parameters in a service, so I will need to load the json file content before any controller is loaded but with service units available
  • Using an external json file is a must in my case here as the app client need to be able to update the app configuration easily from external file without the need to go through the app sources.

Angularjs Solutions


Solution 1 - Angularjs

EDITED

It sounds like what you are trying to do is configure a service with parameters. In order to load the external config file asynchronously, you will have to bootstrap the angular application yourself inside of a data load complete callback instead of using the automatic boostrapping.

Consider this example for a service definition that does not actually have the service URL defined (this would be something like contact-service.js):

angular.module('myApp').provider('contactsService', function () {

	var options = {
		svcUrl: null,
		apiKey: null,
	};

	this.config = function (opt) {
		angular.extend(options, opt);
	};

	this.$get = ['$http', function ($http) {

		if(!options.svcUrl || !options.apiKey) {
			throw new Error('Service URL and API Key must be configured.');
		}

		function onContactsLoadComplete(data) {
			svc.contacts = data.contacts;
			svc.isAdmin = data.isAdmin || false;
		}

		var svc =  {
			isAdmin: false,
			contacts: null,
			loadData: function () {
				return $http.get(options.svcUrl).success(onContactsLoadComplete);
			}
		};

		return svc;
	}];
});

Then, on document ready, you would make a call to load your config file (in this case, using jQuery). In the callback, you would then do your angular app .config using the loaded json data. After running the .config, you would then manually bootstrap the application. Very Important: do not use the ng-app directive if you are using this method or angular will bootstrap itself See this url for more details:

http://docs.angularjs.org/guide/bootstrap

Like so:

angular.element(document).ready(function () {
	$.get('/js/config/myconfig.json', function (data) {

		angular.module('myApp').config(['contactsServiceProvider', function (contactsServiceProvider) {
			contactsServiceProvider.config({
				svcUrl: data.svcUrl,
				apiKey: data.apiKey
			});
		}]);

		angular.bootstrap(document, ['myApp']);
	});
});

UPDATE: Here is a JSFiddle example: http://jsfiddle.net/e8tEX/

Solution 2 - Angularjs

I couldn't get the approach suggested my Keith Morris to work.

So I created a config.js file and included it in index.html before all the angular files

config.js

var configData = {
    url:"http://api.mydomain-staging.com",
    foo:"bar"
}

index.html

...
<script type="text/javascript" src="config.js"></script>
<!-- compiled JavaScript --><% scripts.forEach( function ( file ) { %>
<script type="text/javascript" src="<%= file %>"></script><% }); %>

then in my run function I set the config variables to $rootScope

.run( function run($rootScope) {
    $rootScope.url = configData.url;
    $rootScope.foo = configData.foo;
    ...
})

Solution 3 - Angularjs

You can use constants for things like this:

angular.module('myApp', [])

// constants work
//.constant('API_BASE', 'http://localhost:3000/')
.constant('API_BASE', 'http://myapp.production.com/')
//or you can use services
.service('urls',function(productName){ this.apiUrl = API_BASE;})

//Controller calling
.controller('MainController',function($scope,urls, API_BASE) {
     $scope.api_base = urls.apiUrl; // or API_BASE
});

//in html page call it {{api_base}}

There are also several other options including .value and .config but they all have their limitations. .config is great if you need to reach the provider of a service to do some initial configuration. .value is like constant except you can use different types of values.

https://stackoverflow.com/a/13015756/580487

Solution 4 - Angularjs

Solved by using constant. Like providers you can configure it in .config phase. Everything else like Keith Morris wrote before. So the actual code would be look like this:

(function () {
var appConfig = {

};

angular.module('myApp').constant('appConfig', appConfig);
})();

then in app.bootstrap.js

(function () {

angular.element(document).ready(function () {

    function handleBootstrapError(errMsg, e) {
        console.error("bootstrapping error: " + errMsg, e);
    }

    $.getJSON('./config.json', function (dataApp) {
        angular.module('myApp').config(function (appConfig) {
            $.extend(true, appConfig, dataApp);
            console.log(appConfig);
        });

        angular.bootstrap(document, ['myApp']);

    }).fail(function (e) {
        handleBootstrapError("fail to load config.json", e);
    });

});
})();

Solution 5 - Angularjs

To json config file, there is a practice example on Jaco Pretorius blog's. Basically:

angular.module('plunker', []);
angular.module('plunker').provider('configuration', function() {
  let configurationData;
  
  this.initialize = (data) => {
    configurationData = data;
  };
  
  this.$get = () => {
    return configurationData;
  };
});

angular.module('plunker').controller('MainCtrl', ($scope, configuration) => {
  $scope.externalServiceEnabled = configuration.external_service_enabled;
  $scope.externalServiceApiKey = configuration.external_service_api_key;
});

angular.element(document).ready(() => {
  $.get('server_configuration.json', (response) => {
    angular.module('plunker').config((configurationProvider) => {
      configurationProvider.initialize(response);
    });
    
    angular.bootstrap(document, ['plunker']);
  });
});

Plunker: http://plnkr.co/edit/9QB6BqPkxprznIS1OMdd?p=preview

Ref: https://jacopretorius.net/2016/09/loading-configuration-data-on-startup-with-angular.html, last access on 13/03/2018

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMChanView Question on Stackoverflow
Solution 1 - AngularjsKeith MorrisView Answer on Stackoverflow
Solution 2 - AngularjsmikeView Answer on Stackoverflow
Solution 3 - AngularjstommybananasView Answer on Stackoverflow
Solution 4 - AngularjsDionis OlenView Answer on Stackoverflow
Solution 5 - AngularjsGilberto AlexandreView Answer on Stackoverflow