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>

1

3 Answers 3

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);
    });
  });
Sign up to request clarification or add additional context in comments.

Comments

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>

Comments

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.