Sriram Thiagarajan Sriram Thiagarajan - 4 months ago 30
AngularJS Question

View is not updated after the $http async call when using controllerAs syntax

I am learning angularjs and I am trying to use the controllerAs syntax as I am from Java background and this would make more sense to me but I am having trouble understanding the digest loop.

I am trying to do a http call and update the variable in the controller.When I am using $scope in controller the view is updated after the data is received but when I am using the controllerAs syntax the view is not updated.

Codepen with $scope Syntax

http://codepen.io/eternal15/pen/BzANEw?editors=1111

<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.min.js"></script>
</head>
<body ng-app="Test" ng-controller="testCtrl">
{{output}}
<button ng-click="onClick()">Test</button>
</body>

</html>
//JS FILE
angular.module("Test", []).controller('testCtrl', ['$scope','$http', function($scope, $http){
$scope.output = "Loading";
$scope.onClick = function(){
console.log('clicked');
$http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){
$scope.output = "worked!!";
console.log($scope.output);
})
}
}]);


Codepen with controllerAs Syntax (View not updated)

http://codepen.io/eternal15/pen/yJKoaZ?editors=1011

<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.min.js"></script>
</head>
<body ng-app="Test" ng-controller="testCtrl as test">
{{test.output}}
<button ng-click="test.onClick()">Test</button>
</body>

</html>
//JS File
angular.module("Test", []).controller('testCtrl', ['$http', function($http){
this.output = "Loading";
this.onClick = function(){
console.log('clicked');
$http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){
this.output = "worked!!";
console.log(this.output);
})
}
}]);


I have read about the controllerAs syntax and I think it would add the object (test in the example above) under scope and thus the variables are accessible using (test) object.

So the digest loop runs after $http call because the view is updated in the first example using $scope. Since the digest loop is executed the object test in the second example should also be updated right?

Also i tried to inject $scope and do $scope.$apply() and that also didn't work and it gave me this error

Error: [$rootScope:inprog] http://errors.angularjs.org/1.5.2/$rootScope/inprog?p0=%24digest


I would like to know what I am doing wrong. Although i could go back to using the $scope format, I would like to know if I am doing something wrong or should I add other statements to watch the variables and update the values manually.

Thanks in advance

Answer

this has a different meaning inside function. Assign this to a variable and use it. Try:

angular.module("Test", []).controller('testCtrl', ['$http', function($http){
  var vm = this;
  vm.output = "Loading";
  vm.onClick = function(){
    console.log('clicked');
    $http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){ 
      vm.output = "worked!!";
      console.log(vm.output);
    })
  }
}]);