35

I have the following $rootScope variable which I use to save the current logged in user privilege level, then I access this variable from other controllers. Is there a way I can watch the rootScope variable for changes in order to update controllers specific variables with any changes to the root scope variable? Below is the code I am using so far, can someone please tell me what I am doing wrong and how to fix it? Thanks

In app.js under .run:

 $rootScope.uPLevel = 0;

.controller

   $scope.$watch($rootScope.uPLevel, function() {
            $scope.userPLevel = $rootScope.uPLevel;
   }, true);

2 Answers 2

64

The first parameter to $watch should either be a string or a function (docs). Right now you're passing it the value of $rootScope.uPLevel on controller initialization.

$scope.$watch(function() {
  return $rootScope.uPLevel;
}, function() {
  $scope.userPLevel = $rootScope.uPLevel;
}, true);

Two sidenotes:

  • It may be prudent to store this value in a service instead of $rootScope.
  • If uPLevel is only an integer (as your example suggests) then you don't need to pass true as the third parameter - that's only for arrays and objects. If you do want to watch a collection, then I suggest using $watchCollection instead.
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot, reason I am using it in rootScope as I need a way to have it accessible from all services / controllers application wide. Do you believe having this variable inside a service is much better? if yes can you please explain why?
@MChan It's generally a bad idea to clutter up $rootScope for the same reasons one doesn't attach lots of variables to window. Something to think about. Don't forget to upvote!
@SomeKittensUx2666 is right that you should resist putting things on $rootScope, in this case I would suggest that you broadcast an event from $rootScope which all controllers/services could listen to in order to handle the change logic.
or you could use a single object and store all data inside it. this way you don't clutter the $rootScope
Plus one more vote because if you have a dynamic value to watch that is not isolated well in a specific scope, even if it's on the $window, this is a good way to go.
30

I recommend watching $rootScope variables like that:

$scope.$watch('$root.uPLevel', function() {
    $scope.userPLevel = $rootScope.uPLevel;
});

This way, When current directive/controller is destroyed. It clears the watch as well. In $rootScope.$watch case, the watch stays forever.

1 Comment

Great idea. Perfect if you're looking for performance optimization

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.