Why is AngularJs not updating after an asynchronous Ajax call?

Why isn't the view updated to Someone?

var app = angular.module('Async', []);

app
  .controller('MainController', function($scope) {
    $scope.user = {
      name: "No one"
    };

    jQuery.ajax("/"
      , {
        async: true,
        type: "POST",
      }
    ).always(function() {
      $scope.user.name = "Someone";
      alert($scope.user.name);
    });
  });

angular.bootstrap(document, ['Async']);
      

<div data-ng-controller="MainController">
  <div data-ng-view="">User name: {{ user.name }}</div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.js"></script>
      

Run codeHide result


+3


source to share


3 answers


When you make asynchronous calls like this outside of the angular world, you need to tell angular about any changes you make. There are several ways to solve this problem:

First option: start $ scope. $ apply () in your callback to tell angular that you are changing things:

jQuery.ajax("/"
  , {
    async: true,
    type: "POST",
  }
).always(function() {
  $scope.apply(function() {
    $scope.user.name = "Someone";
    alert($scope.user.name);
  })
});

      



Second option (preferred): replace the call jQuery.ajax

with angular's inline $http

that takes care of the $ apply step for you:

app
  .controller('MainController', function($scope, $http) {
    $scope.user = {
      name: "No one"
    };

    $http({
      method: 'POST',
      url: '/'
    }, function(successResponse) {
      $scope.user.name = successResponse.data.name;
      alert($scope.user.name);
    });
  });

      

+5


source


You are using jQuery instead of angular's $ http service to make the ajax request, so you need to manually call $ scope. $ apply () after changing the scope.



var app = angular.module('Async', []);

app
  .controller('MainController', function($scope) {
    $scope.user = {
      name: "No one"
    };

    jQuery.ajax("/"
      , {
        async: true,
        type: "POST",
      }
    ).always(function() {
      $scope.user.name = "Someone";
      $scope.$apply();
      alert($scope.user.name);
    });
  });

angular.bootstrap(document, ['Async']);
      

<div data-ng-controller="MainController">
  <div data-ng-view="">User name: {{ user.name }}</div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.js"></script>
      

Run codeHide result


+2


source


The problem is your ajax handler is working outside of AngularJS. You can replace your jQuery

ajax call with AngularJs $http

or use $ scope. $ apply (see: https://docs.angularjs.org/api/ng/type/$rootScope.Scope )

+1


source







All Articles