Let's say I'm using a class (acting more like a kind of struct) representing a string value, with the side-effect that it changes its value every time you access it:
function Foo() {
var value = 'a';
this.getValue = function() {
if (value == 'a') {
value = 'b';
return 'a';
}
else {
value = 'a';
return 'b';
}
}
}
..and I override it's toString()
method:
Foo.prototype.toString = function() {
return this.getValue();
}
Outputting this value is fine with a direct reference:
var foo = new Foo();
alert(foo); //a
document.getElementById('bar').innerHTML = foo; //b
However, outputting the object with an AngularJS expression results in {}
being displayed rather than the toString()
/getValue()
value:
var foo = new Foo();
var app = angular.module('main', []);
app.controller('ctrl', function($scope) {
$scope.val = foo;
alert($scope.val); //a (has not been changed by previous line)
});
..and then:
<div ng-app="main" ng-controller="ctrl">{{val}}</div> //{} (rather than b)
I could just use $scope.val = foo.getValue();
, $scope.val = foo.toString();
or even $scope.val = foo + '';
, and according to Is it possible to provide an implicit way of converting object into string for angular templates? ng-bind
calls the toString()
method, but why is it not called when Angular evaluates the object in an expression?