Why would AngularJS load $scope twice?

The other day I was working on an Angular project and noticed that my controller scope had loaded twice. I noticed this phenomenon using Batarang:

Two scopes loading in batarang

Tip: Batarang is a great chrome developer tool plugin that helps a lot with debugging your Angular applications.

Where in the world did scope.$id=2 come from? The rest of the structure seemed completely normal, but here was this extra element showing and it had a scope attached to it. When I compared the two scopes they looked almost identical!

scope.$id=2 scope:
id two scope is identical to id 3

ng-controller scope:
id3 scope is identical to id2

As you can see only the $id of the two scopes is different and the controller scope is nested under the $id=2 scope.

The other strange thing that happened was that when I modified the form, only the controller scope (id 3) updated. The $id=2 scope didn’t change no matter what I did on the form!

Based on this I started thinking that there was some sort of prototypical inheritance issue occurring between Angular elements on my page. I researched this theory for quite a while but still couldn’t determine the root cause. Finally I discovered the answer:

My controller was loading twice because I had declared it both in both the route and the template.
Angular was literally loading my scope twice, just like I had asked it to! Once I removed one of the declarations, the extra scope went away and all was well.

Here are the two places I was loading the controller. Once in the route setup in app.js:

$routeProvider
    .when('/', {
        templateUrl: 'app/controllers/4-ControllerAs/example.tpl.html',
        controller: 'ExampleController as ctrl'
    });

and then again when defining my controller in the template:

<div class="container float-left" ng-controller="ExampleController as ctrl">

One thing that makes this type of bug really dangerous is that the application still works correctly. Because of this it can be a very difficult bug to discover. If you didn’t pay close attention to your scopes in a tool like Batarang, you may not even notice this occurring.

Also, if your controller does any type of resource calls during the loading process then this will all happen twice! It could be very easy to end up with all of your service calls executing multiple times. If you wired up all of your controllers this way, your entire app would do a lot of its initial loading twice!

Tip: Keep a close eye on the scopes and resource calls of your app.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s