Does AngularJS always know when something has changed, it's time to update?

I am reading AngularJS in Action by Lukas Ruebbelke to clear the concept of dirty checking as to how AngularJS works at a molecular level.

The author puts forward,

It is during the digest cycle that all watch expressions for a scope object are evaluated. When a watch expression detects that a $scope property has changed, then a listener function is fired. Ocassionally a property is changed without AngularJS knowing about it. You
can manually kickstart a digest cycle vis $apply.

So, my question is what are those situations in a real web application when I need to kick off this digest cycle manually. And are those situations often seen? Kindly suggest.

Upvotes: 2

Views: 76

Answers (2)

olee
olee

Reputation: 747

These situations can happen when using 3rd party libraries which provide some kind of data for example.

Say you use library-X which fires an event when something happened and new data is available, which you would like to render with AngularJS. In these causes AngularJS does not know that data in the scope changed if you just directly set the variables.

That is why you should only modify scope variables inside the $apply function:

function MyController($scope) {
    $scope.load = function() {
        $scope.message = 'Loading...';
        setTimeout(function() {
            $scope.$apply(function () {
                $scope.message = 'Finished loading!';
            });
        }, 2000);
    }
}

It is also advised to use $scope.$apply(function () { /* update code */ }) instead of the single $scope.$apply() call, since it will properly catch errors and run the diggest regardless of any errors.

Upvotes: 1

rob
rob

Reputation: 18513

This will come up any time an asynchronous callback returns from a non-angular library. e.g.

setTimeout(function() {
    $scope.myVar = 1;
    //Angular doesn't know when setTimeout finishes 
    //so you have to manually kick off a digest cycle.
    $scope.$apply();
});

Angular has the $timeout service which takes care of starting a digest cycle for you but if you are using some third party library that takes a callback and doesn't have an angular wrapper then you will have to do this.

Upvotes: 2

Related Questions