4

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?

Community
  • 1
  • 1
Callan Heard
  • 727
  • 1
  • 8
  • 18

0 Answers0