AngularJS GlobalCtrl vs $rootScope vs Service

All we need is an easy explanation of the problem, so here it is.

I am confused on a couple of things with Globals in Angular. Below is my pseudo code.

1) With the way I have my GlobalCtrl placed, I am able to reference my $scope.modalOptions from all of my controllers. That being the case, I’m confused as to why I see people adding global properties to $rootScope instead of just adding them like I am doing here. Is that just in case they want to inject it into a service or something?

2) Should I be using a service instead of adding properties and methods to my GlobalCtrl? If so, why?

<div ng-app="app" ng-controller="GlobalCtrl">
    <div ng-view></div>
</div>

function GlobalCtrl($scope, $location) {
    $scope.modalOptions = {
        backdropFade: true,
        dialogFade: true
    };
}

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

The ‘Main Controller’ approach is definitely preferable to using $rootScope.

Scope inheritance is there, so why not leverage it. In my opinion, that solution works well for most cases, i.e. unless you need to have a parallel controller somewhere (that wouldn’t be a child of Main). In that case, the best way to go is to use a service and inject it where needed. Services (or rather factories, because that’s what you’ll probably be using — read more about them here) are singletons and work well for sharing data across controllers.

Important to know about scopes

Scope inheritance is pretty much regular JavaScript inheritance at play. You should tend to use objects for your data, because they are passed by reference.

If you have a primitive like $scope.myString = 'is of a primitive data type'; in your parent controller and try to overwrite the value in a child controller, the result won’t be what you’d expect — it will create a new string on the child controller instead of writing to the parent.

Suggested reading here

Final thoughts

If you are using the nested controllers approach, do not forget to still inject $scope (and other dependencies) in the child controller. It might work without, but it’s slower and hard to test, and last but not least — the wrong way to do it.

Finally, if you have a lot of state variables to keep track of and/or a lot of usage points, it’s definitely a good idea to extract them into a service.

Method 2

Generally speaking global variables are considered bad practice, as they don’t encourage encapsulation, make debugging difficult, and promote bloated code. Here’s a good discussion of global variables: http://c2.com/cgi/wiki?GlobalVariablesAreBad.

A good rule of thumb is to add properties and methods to the most local scope possible and use services to share data between modules.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply