2

Trying to figure out why when the console tells me one thing but angular's output to html tells me another.

Code

angular.module('global',[]);

angular.module('global').controller('thisTestController', thisTestController);
function thisTestController() {
  var tc = this;  
  tc.status = "not loaded";

  function activate() {

    var background = new Image();
    background.onload = function () {
        tc.status = "loaded";
        console.log(tc.status);
    };
    background.src = 'http://placehold.it/350x150';

  }

  activate();

}

HTML

  <body ng-app="global">
     <div ng-controller="thisTestController as tc">Status = {{tc.status}}</div>
  </body>

Result

Console.log - loaded
HTML - Status = not loaded

http://plnkr.co/edit/wxja7smqOJiSbUi7mfu4?p=preview

mls3590712
  • 750
  • 1
  • 6
  • 20
  • Possible duplicate of [Angularjs service callback to update scope of controller](http://stackoverflow.com/questions/18931689/angularjs-service-callback-to-update-scope-of-controller) – Brian Nov 18 '15 at 22:43
  • read about `$digest` http://www.sitepoint.com/understanding-angulars-apply-digest/ – Namek Nov 18 '15 at 22:43
  • to trigger the $digest safety, you can use `$timeout` http://plnkr.co/edit/ZRDCroSxPLWHKd6YjHVC?p=preview – jan Nov 18 '15 at 22:50

2 Answers2

4

You need to bind your controller with $scope, like this: http://plnkr.co/edit/CV7rgBGQMnRlNDnYSQIq?p=preview

angular.module('global', []);

angular.module('global').controller('thisTestController', thisTestController);

function thisTestController($scope) {
  var tc = this;
  tc.status = "not loaded";

  function activate() {

    var background = new Image();
    background.onload = function() {
      tc.status = "loaded";
      $scope.$apply();
      console.log(tc.status);
    };
    background.src = 'http://placehold.it/350x150';

  }

  activate();

}
LYu
  • 2,316
  • 4
  • 21
  • 38
  • It's a bad practice to use `$apply()` without the function argument because behind the scenes they wrap the function in a `try,catch` and in turn pass it to the $exceptionHandler service. Also, you should always have $apply in a timeout because of conflicts if something else is updating. – technicallyjosh Nov 18 '15 at 23:51
1

You need to use $scope and $scope.$apply to update values after the context has been rendered. tc (this) has no context in the lifecycle of the controller. In other words, your tc assignment is really just the function itself. Not the binding context for the controller.

I have a forked version of your plnkr with a simple example to get it working.

http://plnkr.co/edit/fghSbSsarBbM0zv5EzoB?p=preview

Docs for $scope and $apply can be found here:

angular docs

technicallyjosh
  • 3,511
  • 15
  • 17