Troubleshooting Nested Scopes in Angular
Many beginner Angular tutorials start with a set of canned data, an input field, and a search filter, so it was a natural place to start on my side project, Virtual Playbill. With even a small data set, watching the DOM change based on search criteria was a thrilling achievement. In the intervening months, as features were added, rebuilt, or taken away, I had inadvertently broken the search box. The tutorials were still available, and still fairly basic, but I couldn’t get it to work. Not until I found a couple of invaluable tools for troubleshooting overlapping scopes:
1. Use the developer tools console
This handy trick will give you a console object corresponding to that element’s scope:
- select a DOM element in using the chrome developer tools
angular.element($0).scope()into the console pane (
$0is a global variable holding a reference to the selected DOM element)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Things are definitely looking different between the scope containing my search box and the scope where I am laying out the view: the second scope appears to be a sibling of the first. I needed something a little more visual before it completely sunk in, though.
2. Use ng-inspector
ng-inpector is a browser extension that allows you to navigate your angular app as if it were a file directory:
I can see at a glance that the scope containing the search box (#2), is separate from the scope where I am laying out my view (the unnamed scope #5).
Because of these tools, I have learned that multiple instances of the same controller do not share scope. Using ng-router, I declared the controller for the view:
1 2 3 4 5 6
In my layout, I had declared the controller once more:
1 2 3 4 5 6 7 8 9
The search box was already in the context of a Playbill Controller, and I had inadvertently put in another. The solution was to simply remove the second ng-controller:
1 2 3 4 5 6 7 8 9
I have been growing my Ruby/Rails troubleshooting toolbox for a while now, and it is good to get one started for angular as well.