Is there a good way to dump or inspect the results of an expression? Sometimes when I do
{{some_expression}}
, nothing shows up on the page where the result of that expression should show up. How do I determine if the expression returned a null
, an undefined
, or an empty string ''
?
If it's a normal object, like this, it will show a nice programmer-friendly representation of the object, which is great:
{{ {'a': 1} }}
But if you try to inspect an expression that evaluates to null, undefined, or '', they are all indistinguishable from each other!
{{null}}
{{undefined}}
{{''}}
So how can you tell which one it was??
I tried using JSON.stringify
:
{{ JSON.stringify(null) }}
but JSON
seems to be unavailable from an Angular expression because it's a method from window
and not a property of the scope (see related question about accessing methods from window).
I tried using typeof
:
typeof {}: {{ typeof {'a': 1} }}
but it results in an error:
Error: [$parse:syntax] Syntax Error: Token '{' is an unexpected token at column 9 of the expression [ typeof {'a': 1} ] starting at [{'a': 1} ].
So how can I get it to dump the value into the template using something like JSON.stringify
(… or console.log
)?
Generally speaking, is there a good way to debug Angular expressions other than trial and error? Since Angular expressions are so "forgiving", they don't seem to raise errors; they just silently swallow the errors and return undefined
:
In JavaScript, trying to evaluate undefined properties generates ReferenceError or TypeError. In Angular, expression evaluation is forgiving to undefined and null.
But without seeing some kind of error message, how do you know what part of the expression Angular had trouble with?
The ng-bind directive tells AngularJS to replace the content of an HTML element with the value of a given variable, or expression. If the value of the given variable, or expression, changes, the content of the specified HTML element will be changed as well.
The ng-bind-html directive is a secure way of binding content to an HTML element.
AngularJS expressions are JavaScript-like code snippets that are mainly placed in interpolation bindings such as <span title="{{ attrBinding }}">{{ textBinding }}</span> , but also used directly in directive attributes such as ng-click="functionExpression()" . For example, these are valid expressions in AngularJS: 1+2.
You can add a custom filter for debugging purposes:
app.filter('debug', function() {
return function(input) {
if (input === '') return 'empty string';
return input ? input : ('' + input);
};
});
Usage:
{{ value | debug }}
Demo: http://plnkr.co/edit/U44BCjBhgsFedRkHASlc?p=preview
The recommended way is to use AngularJS's logging service $log
. First you need to inject the service into your controller and assign it to a scope variable like so:
app.controller('MyCntrl', function($log){
$scope.$log = $log;
Then in your template, us it like ay other function:
<span>{{$log.log(value}}</span>
If you want to be able to use typeof, it works basically the same way:
$scope.getTypeOf = function(val){ return typeof val; };
<span>{{getTypeOf(val)}}</span>
The built-in JsonPipe might be easier...
{{ object | json }}
See: https://angular.io/api/common/JsonPipe
Based on tasseKATT's and ogc-nick's great answers, I added these two filters. They're written in CoffeeScript but here's the JavaScript equivalent if you prefer. Posting here in case it's helpful to anyone else...
.filter 'debug', ->
(input) ->
if typeof input is 'undefined'
'undefined'
else
JSON.stringify(input)
.filter 'typeof', ->
(input) ->
typeof input
Now I can get some meaningful debugging output from each of the following expressions:
{{null | debug}}
{{undefined | debug}}
{{'' | debug}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With