3

Why the view is not 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's 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>
Mehran
  • 15,593
  • 27
  • 122
  • 221
  • possible duplicate of [Angular controller scope not updating after jQuery ajax call](http://stackoverflow.com/questions/21127709/angular-controller-scope-not-updating-after-jquery-ajax-call) – Gruff Bunny Oct 15 '14 at 17:46

3 Answers3

5

When you are doing asynchronous calls like this outside of the angular world, you need to inform angular of any changes that you've made. There are a couple ways to fix this problem:

First Option: Run $scope.$apply() within your callback to inform angular 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 jQuery.ajax call with angular's built-in $http, which will take 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);
    });
  });
Wade Tandy
  • 4,026
  • 3
  • 23
  • 31
2

You use jquery instead of angular $http service to make ajax request, so you should manually call $scope.$apply() after scope changes.

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's 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>
Alexey
  • 1,257
  • 7
  • 13
1

The problem is that your ajax handler is running outside AngularJS. You can replace your jQuery ajax call by AngularJs $http or use $scope.$apply (see: https://docs.angularjs.org/api/ng/type/$rootScope.Scope)

OXMO456
  • 3,558
  • 2
  • 25
  • 35