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>
source to share
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);
});
});
source to share
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>
source to share
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 )
source to share