Sahan H.
Sahan H.

Reputation: 472

AngularJS data binding and jQuery promises

Inside my angular controller I have the following method defined

$scope.searchListing = function() {
    $http({
        url: App.Url.to('listing/feed/21312')
    }).success(function(data, status, headers, config) {
        $scope.data = data;
    });
}

In view, $scope.data.listing is looped

<div class="item" ng-repeat="property in data.listings"><!-- stuff --></div>

searchListing is triggered using ng-click and the things works perfectly. However I have a separate API which handles the API calls to my app, and it's based on jQuery. After integrating my jQuery based API

$scope.searchListing = function() {
    App.Listing.getListing().done(function(data){
        $scope.data = data;
    });
}

The API returns jqXHR objects so I can call promise methods on them. The problem is even though the data get assigned to $scope.data my view doesn't get updated. After the ajax request completed I accessed the controller to check if data got assigned

angular.element('[ng-controller=listingController]').scope().data

And it did show the data, why doesn't the view get updated?

Upvotes: 1

Views: 1056

Answers (1)

Ayush
Ayush

Reputation: 42440

When data in the Angular model ($scope), changes, Angular recognizes this and triggers a digest loop which re-renders the view with the updated data.

However, when this data change happens in a callback that is outside of Angular's viewport, Angular is unable to monitor the change. This is happening in your case where the data change is happening in a jQuery promise, which is not part of Angular. In this case, you need to manually trigger the digest loop like this:

App.Listing.getListing().done(function(data){
        $scope.data = data;

        // make sure your app is not currently in a digest loop
        if (!$scope.$$phase)
            $scope.$apply(); // trigger digest loop
});

Upvotes: 2

Related Questions