For debugging AngularJS in Chrome you can use AngularJS Batarang.
(From recent reviews on the plugin it seems like AngularJS Batarang is no longer being maintained. Tested in various versions of Chrome and it does not work.)
IMHO, the most frustrating experience comes from getting / setting a value of a specific scope related to an visual element. I did a lot of breakpoints not only in my own code, but also in angular.js itself, but sometimes it is simply not the most effective way.
Although the methods below are very powerful, they are definitely considered to be bad practice if you actually use in production code, so use them wisely!
Get a reference in console from a visual element
In many non-IE browsers, you can select an element by right clicking an element and clicking "Inspect Element". Alternatively you can also click on any element in Elements tab in Chrome, for example. The latest selected element will be stored in variable $0 in console.
Get a scope linked to an element
Depending on whether there exists a directive that creates an isolate scope, you can retrieve the scope by angular.element($0).scope() or angular.element($0).isolateScope() (use $($0).scope() if $ is enabled). This is exactly what you get when you are using the latest version of Batarang. If you are changing the value directly, remember to use scope.$digest() to reflect the changes on UI.
$eval is evil
Not necessarily for debugging. scope.$eval(expression) is very handy when you want to quickly check whether an expression has the expected value.
The missing prototype members of scope
The difference between scope.bla and scope.$eval('bla') is the former does not consider the prototypically inherited values. Use the snippet below to get the whole picture (you cannot directly change the value, but you can use $eval anyway!)
scopeCopy = function (scope) {
var a = {};
for (x in scope){
if (scope.hasOwnProperty(x) &&
x.substring(0,1) !== '$' &&
x !== 'this') {
a[x] = angular.copy(scope[x])
}
}
return a
};
scopeEval = function (scope) {
if (scope.$parent === null) {
return hoho(scope)
} else {
return angular.extend({}, haha(scope.$parent), hoho(scope))
}
};
Use it with scopeEval($($0).scope()).
Where is my controller?
Sometimes you may want to monitor the values in ngModel when you are writing a directive. Use $($0).controller('ngModel') and you will get to check the $formatters, $parsers, $modelValue, $viewValue$render and everything.
Unfortunately most of add-ons and browser extensions are just showing the values to you but they don't let you to edit scope variables or run angular functions. If you wanna change the $scope variables in browser console (in all browsers) then you can use jquery. If you load jQuery before AngularJS, angular.element can be passed a jQuery selector. So you could inspect the scope of a controller with
angular.element('[ng-controller="name of your controller"]').scope()
You need to change value of $scope variable and see the result in the browser then just type in the browser console:
angular.element('[ng-controller="mycontroller"]').scope().var1 = "New Value";
angular.element('[ng-controller="mycontroller"]').scope().$apply();
You can see the changes in your browser immediately. The reason we used $apply() is: any scope variable updated from outside angular context won't update it binding, You need to run digest cycle after updating values of scope using scope.$apply() .
For observing a $scope variable value, you just need to call that variable.
You wanna see the value of $scope.var1 in the web console in Chrome or Firefox just type:
Since the add-ons don't work anymore, the most helpful set of tools I've found is using Visual Studio/IE because you can set breakpoints in your JS and inspect your data that way. Of course Chrome and Firefox have much better dev tools in general. Also, good ol' console.log() has been super helpful!
You must launch Chrome with remote debugging enabled in order for the extension to attach to it.
Windows
Right click the Chrome shortcut, and select properties
In the "target" field, append --remote-debugging-port=9222
Or in a command prompt, execute /chrome.exe --remote-debugging-port=9222
OS X
In a terminal, execute /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
Linux
In a terminal, launch google-chrome --remote-debugging-port=9222