I've altered the settings file to just a JS file, added var tempSettings =
to the beginning of the file, and added it in index.html. This way it gets loaded with the initial HTML, ensuring it will exist when app.run goes. The settings service then takes this tempSettings
variable and puts it in the service. To clean up, I remove the tempSettings pointer.
New settings file called settings.js
var tempSettings = {
"environment": "development",
[...]
Added to index.html:
<script src="settings.js"></script>
Service:
myApp.service("settings", function(){
var settings = null;
this.initialize = function() {
settings = tempSettings;
tempSettings = undefined;
};
this.get = function() {
return settings;
}
});
Because the settings file is loaded async, it sometimes happens that a module tries to use the settings before they are loaded. I'll keep you updated on solutions. I have moved the settings into a service, that is definitely better.
When I google how to store environment settings in AngularJS apps, I come across options using Grunt or Gulp (and there's probably others as well), but to me this option seems much more obvious. Meaning that there's probably a good reason not to use it. Is this way of storing settings a bad idea?
I have in my app root a file called settings.json which looks something like this:
{
"settingsFile": true,
"environment": "development",
"logLevel": "debug",
"userApiBase": "http://localhost/covlelogin/web/api/",
"oAuth": {
"google":{
"endpoint": "https://accounts.google.com/o/oauth2/auth",
"clientId": "12345",
"scope": "email profile",
"state": "MyToken123",
"redirectUri": "http://localhost/loginadmin/web/oAuthRedirect",
"responseType": "code",
"approvalPrompt": "force"
}
}
}
I then have a little bit in app.run that looks like this:
MyApp.run(function ($rootScope, $http) {
//Load settings
$http.get('settings.json').
success(function (settings) {
if (settings.settingsFile){
$rootScope.settings = settings;
console.log("Settings loaded");
}else{
console.log("Error loading settings. File may be corrupt.");
//Additional error handling
}
}).
error(function (data) {
console.log("Error getting settings file.");
//Additional error handling
})
});
And now whenever I need a setting I can always go to $rootScope.settings.userApiBase
or whatever. It makes sense to me, because all I have to do is to make sure settings.json is ignored on check-in. The whole method is really straight forward. Is there a flaw to this design?
Try not to pollute the $rootScope
Here as much as possible. Make a Settings service that handles the settings instead. Services are singleton objects so once you initialize
the service, the settings will be available everywhere you inject the service.
MyApp.service("Settings", function($http) {
var settings = null;
this.initialize = function() {
$http.get('settings.json').success(function (s) {
if (s.settingsFile){
settings = s;
console.log("Settings loaded");
} else {
console.log("Error loading settings. File may be corrupt.");
//Additional error handling
}
}).error(function (data) {
console.log("Error getting settings file.");
//Additional error handling
})
};
this.get = function() {
return settings;
}
return this;
});
And in MyApp.run
:
MyApp.run(function (Settings) {
Settings.initialize();
}
Then, whenever you want to access Settings
in a controller or another service or something, simply call Settings.get()
which will return your settings. Just make sure to inject the Settings
service into anything that uses it (like I did in the second code block).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With