The subject of global variables in most languages is enough to bring the most passionate code junkies out of the woodwork ready to debate and bite off your feet for even entertaining the thought.
The reality is in a framework like AngularJS globals are warranted at times, but only if you implement globals the Angular way. But not globals in the way you know.
Constants and values
Out of the box, AngularJS supports global constants and values. Obviously constants are read only pieces of data and values are pieces of data that can change at any time, anywhere.
However, it is worth pointing out that setting a constant to have an object of properties and values means you can modify those properties inside of the constant because that is how Javascript works. We will get into this a little later in the examples.
Values like the application name, version and even URL’s to various endpoints like API’s generally should never change within your application and are always constant, so therefore, they should be constants.
Values that can be changed such as storing a count of users online where it can go up and down, would be a better use-case for values as you need to be able to write and read them anywhere in your application or a specific service/provider. Storing session data such as an email, profile ID and names is also another good candidate for values.
It is worth pointing out that constants and values can store more than single or multiple keyed values in objects, you can also use functions and other various methods, but for the sake of keeping things easy and clean, stick to single values and objects.
The benefits
So what are the benefits of using Angular’s constants and values? The fact they are versatile and allow not only storing single values, but also being able to store objects of data and inject them into services, etc all without polluting the global namespace.
They are also testable as they work like any other service and can be injected into directives, controllers and services. It is worth pointing out that constants can be injected everywhere and values are limited to controllers, directives and services.
You can for example inject constants into module.config, but values cannot be injected into a config function call.
Examples
Enough rambling, here are some examples of setting constants and values, and then accessing them from various parts of your application all without having to create one single dirty Javascript variable.
Constants
Constants and values are pretty much the same with a couple of differences. As mentioned earlier, constants can be injected anywhere including configuration calls. So when you call module.config and set up states or other runtime settings you can inject constant values, but not values.
Also, as mentioned earlier, there is one caveat with constants that can cause them to be editable and that is using anything other than a primitive. Values other than primitives are treated as objects. When using objects with a constant they can be modified, which for a constant makes no semantic sense whatsoever.
This is not to say you can NOT use an object inside of a constant, as long as you or other developers do not modify any of the values contained therein. It is best to stick with values below if you want to modify values.
// Storing a single constant value
var app = angular.module(‘myApp’, []);
app.constant(‘appName’, ‘My App’);
// Now we inject our constant value into a test controller
app.controller(‘TestCtrl’, [‘appName’, function TestCtrl(appName) {
console.log(appName);
}]);
// Storing multiple constant values inside of an object
// Keep in mind the values in the object mean they can be modified
// Which makes no sense for a constant, use wisely if you do this
var app = angular.module(‘myApp’, []);
app.constant(‘config’, {
appName: ‘My App’,
appVersion: 2.0,
apiUrl: ‘http://www.google.com?api’
});
// Now we inject our constant value into a test controller
app.controller(‘TestCtrl’, [‘config’, function TestCtrl(config) {
console.log(config);
console.log(‘App Name’, config.appName);
console.log(‘App Name’, config.appVersion);
}]);
Values
Constants and values are pretty much the same, but remember they are for storing pieces of data that are temporary, they can change anywhere, any time. Even though constants can work the same as values, only values should be modifiable. You should not use an object inside of a constant in the place of what should be a value instead.
You will notice the examples are basically the same as constants, the syntax is the same with exception of the fact that we are setting values as well as reading them.
// Storing a single value
var app = angular.module(‘myApp’, []);
app.value(‘usersOnline’, 0);
// Now we inject our constant value into a test controller
app.controller(‘TestCtrl’, [‘usersOnline’, function TestCtrl(usersOnline) {
console.log(usersOnline);
usersOnline = 15;
console.log(usersOnline);
}]);
// Storing multiple values inside of an object
var app = angular.module(‘myApp’, []);
app.value(‘user’, {
firstName: ’‘,
lastName: ’‘,
email: ’’
});
// Now we inject our constant value into a test controller
// Values will be empty
app.controller(‘TestCtrl’, [‘user’, function TestCtrl(user) {
console.log(user);
console.log(‘First name: ’, user.firstName);
console.log(‘Last name: ’, user.lastName);
console.log(‘Email: ’, user.email);
}]);
// Storing multiple values inside of an object
var app = angular.module(‘myApp’, []);
app.value(‘user’, {
firstName: ’‘,
lastName: ’‘,
email: ’’
});
// Now we inject our constant value into a test controller
// Values will be populated inside of controller
app.controller(‘TestCtrl’, [‘$scope’, ‘user’, function TestCtrl($scope, user) {
user.firstName = ‘Dwayne’;
user.lastName = ‘Charrington’;
user.email = ‘dwayne@ilikekillnerds.com’;
console.log(user);
console.log('First name: ', user.firstName);
console.log('Last name: ', user.lastName);
console.log('Email: ', user.email);
// Pass the user values through to the view
$scope.user = user;
}]);
Conclusion
Constants are great for values that never change. If you need to access values within config function calls to configure routes or anything else when your application first starts, constants are what you should use.
Values are great for pieces of data that can and will change. As shown above user data or anything else where you simply want to keep a reference to a changing value stored globally without creating a messy global variable.
Hi Dwayne!
Thank you for your tutorial, I was searching for something like MeteorJS Session in Ionic, finally I found the answer using “Values” here 🙂
Very nice article.
Can we utilize JavaScript Object.Freeze in angular? I’m thinking something like this…
// first define the un-changeable constants javascript way
var constants = constants || {};
constants.environment = “Development”;
constants.webService = “someUrl”;
Object.freeze(constants);
// add to angular
var app = angular.module(‘myApp’, []);
app.constant(‘constants’, constants);
// inject constants into a controller which won’t be able to change
app.controller(‘TestCtrl’, [‘constants’, function TestCtrl(constants) {
console.log(constants.environment);
}]);
Hi,
Thanks so much for your article, this is wonderful and very helpful.
I’m new to angular and was wondering where you would store these values & constants. Would I define them in the app controller? Or would I create a new .js file called app_constants (or something like that) where I’d store constants and app_vars to store values? Appreciate your help
Thank you very much this article is very use full for me .. thank you
Hi,
big thanks for this article! Simple to understand 🙂
very nice
How do you test it?
I just want to say THANK YOU ! This tutorial is very clear and concise ! After readed it, i can tell that it works…so please continue like this !
one suggestion here.. some people might think of using $rootScope coz they want to access stuff in views directly & don’t want to go through pain of injecting manually the constants.. which is bad coz then every $scope in your whole app will have this added stuff…
i.e shitty performance & confusion (naming conflicts)..
So AVOID it..
Perfect!!. Thanks
Can we change constant value also
like
app.controller(‘TestCtrl’, [‘appName’, function TestCtrl(appName) {
appName=’Hello’;
}]);
Is there any way to inject constant/value globally once, means no need to inject in each controller where we will use the constant
Nice article. Thank you. Question though, do you ever have to worry about concurrency issues with values? If so, how would you deal with that?
angular.module(‘whitesquare’).constant(‘whitesquare’,{
name:’jnd’,
class:’a’
});
this is my controller
angular.module(‘whitesquare’).controller(‘WhitesquareCtrl’,function($scope,whitesquare){
$scope.kk=whitesquare;
console.log(whitesquare.name);
whitesquare.name=”rajat”
console.log(whitesquare.name)// it will print rajat
});
here i have changed the constant value also.. then what is difference b/w constant and value
please explain this artical..help me
Very Nice Article… Keep It Up…
is there any way to restrict users to change the object properties from console ( inspect element ). In my application i just want to restrict users to enable or disable the buttons from console ( inspect element). How can I achieve this ?? any leads will be helpful.
Brief and very informative with examples.. Big Thank you. 🙂
Superb explanation.
Could you please refer any book as explanatory as this content for Nodejs, Angularjs or MEAN stack or for all of them?