Categories
angularjs global-variables

Global variables in AngularJS

356

I have a problem where i’m initialising a variable on the scope in a controller. Then it gets changed in another controller when a user logs in. This variable is used to control things such as the navigation bar and restricts access to parts of the site depending on the type of user, so its important that it holds its value. The problem with it is that the controller that initialises it, gets called again by angular some how and then resets the variable back to its initial value.

I assume this is not the correct way of declaring and initialising global variables, well its not really global, so my question is what is the correct way and is there any good examples around that work with the current version of angular?

1

  • 13

    Since this is #1 google result: You can now use app.constant() and app.value() to create app-wide constants and variables. More here: bit.ly/1P51PED

    – Mroz

    Dec 15, 2015 at 16:14

498

You’ve got basically 2 options for “global” variables:

$rootScope is a parent of all scopes so values exposed there will be visible in all templates and controllers. Using the $rootScope is very easy as you can simply inject it into any controller and change values in this scope. It might be convenient but has all the problems of global variables.

Services are singletons that you can inject to any controller and expose their values in a controller’s scope. Services, being singletons are still ‘global’ but you’ve got far better control over where those are used and exposed.

Using services is a bit more complex, but not that much, here is an example:

var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
  return {
      name : 'anonymous'
  };
});

and then in a controller:

function MyCtrl($scope, UserService) {
    $scope.name = UserService.name;
}

Here is the working jsFiddle: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/

19

  • 141

    From the Angular FAQ: Conversely, don’t create a service whose only purpose in life is to store and return bits of data.

    Feb 21, 2013 at 15:52

  • 7

    I’m using the Express + Angular seed by Btford. If I set a variable on the $rootScope in Controller1 say and move to another url (powered by Controller2 say) I can access this variable. However if I refresh the page on Controller2 then the variable is no longer accessible on $rootScope. If I am saving user data on sign in how can I ensure this data is accessible elsewhere even on page refresh?

    May 8, 2013 at 6:53


  • 20

    @JakobStoeck Combine this with this answer and you’re left with putting the data on the rootScope. I don’t think that’s right either. What’s the angular way of storing and returning globally used bits of data?

    Mar 18, 2014 at 23:39


  • 11

    I’m curious what the disadvantages are of a service that is specifically for storing values. Isolated, only injected where you need it, and easily testable. What is the downside?

    – notbrain

    Jan 21, 2015 at 17:54

  • 15

    oh god, why everybody is afraid of reaal global variables, if you know what your app will consist of, just make a real global js variable instead overcomplicating stuff

    – Max Yari

    Jun 26, 2015 at 19:41

99

If you just want to store a value, according to the Angular documentation on Providers, you should use the Value recipe:

var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');

Then use it in a controller like this:

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
}]);

The same thing can be achieved using a Provider, Factory, or Service since they are “just syntactic sugar on top of a provider recipe” but using Value will achieve what you want with minimal syntax.

The other option is to use $rootScope, but it’s not really an option because you shouldn’t use it for the same reasons you shouldn’t use global variables in other languages. It’s advised to be used sparingly.

Since all scopes inherit from $rootScope, if you have a variable $rootScope.data and someone forgets that data is already defined and creates $scope.data in a local scope you will run into problems.


If you want to modify this value and have it persist across all your controllers, use an object and modify the properties keeping in mind Javascript is pass by “copy of a reference”:

myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
    this.change = function(value) {
        clientId.value="something else";
    }
}];

JSFiddle example

6

  • 1

    When I changed the value on one view, the new value is not persistent. How come? Can you please update your answer and let us see how your clientId can be updated?

    – Blaise

    Jul 7, 2014 at 18:22

  • @DeanOr Is it possible to preserve the updated value between refreshes of the page? The value gets reinitialised if I refresh the page.

    – Nabarun

    Jul 19, 2014 at 23:00

  • You’ll have to use something else for that like a cookie, local storage, or database.

    – Dean Or

    Jul 24, 2014 at 17:35

  • 1

    I really like this one the best. I can now modify by build process for dev, stage, and prod

    – jemiloii

    Dec 3, 2016 at 0:09

  • 1

    There is a simple article explaining the use of constants and values similar to Global variables: ilikekillnerds.com/2014/11/…

    – RushabhG

    Apr 5, 2017 at 10:38

37

Example of AngularJS “global variables” using $rootScope:

Controller 1 sets the global variable:

function MyCtrl1($scope, $rootScope) {
    $rootScope.name="anonymous"; 
}

Controller 2 reads the global variable:

function MyCtrl2($scope, $rootScope) {
    $scope.name2 = $rootScope.name; 
}

Here is a working jsFiddle: http://jsfiddle.net/natefriedman/3XT3F/1/

3

  • 2

    This does not work in views of isolated scope directives. See jsfiddle.net/3XT3F/7. But you can use $root to work around it. See jsfiddle.net/3XT3F/10. Thanks to @natefaubion for pointing it out

    Sep 20, 2013 at 15:22

  • 2

    on refresh, $rootScope value would be empty.

    – xyonme

    Jan 16, 2015 at 3:43

  • hardcoding the $rootScope.name equals some value..actually we need to read it and set it there.

    – user2136053

    Jan 16, 2017 at 7:09