• We Code
  • We Design
  • We Develope
  • We Write
  • We Share

menu

Monday, June 2, 2014

AngularJs $apply $digest in Detail With Error Handeling

The best practice to change the value of bindings is $apply . What $apply actually does ? it update the bindings of the page and notify the value has changes . it calls $digest internally and return the promise. Almost whole angular binding run inside $digest.
 $scope.$apply('foo = "bar"');

//or
 $scope.$apply(function(scope) {
scope.foo = 'bar';
});

//or
 $scope.$apply(function(){
$scope.foo = 'bar';
 });


I was trying to change the scope value with ng-click . And i kept getting a error . Error: $apply already in progress.
If you are also facing the same error I found two solution for it
First Solution : you can put the putAsafeApply method , which wil check the status of the $apply .

$scope.putAsafeApply = function(fn) {
var status = this.$root.$$phase;
if(status == '$apply' || status == '$digest') {
 if(fn && (typeof(fn) === 'function')) {
 fn();
 }
 } else {
this.$apply(fn);
}
};


$scope.$$phase or $scope.$root.$$phase will return "$digest" or "$apply" if a $digest or $apply is in progress. I believe the difference between these states is that $digest will process the watches of the current scope and it's children, and $apply will process the watchers of all scopes.

So now we have putAsafeApply method and we can use it where ever we want to use instead of $apply.


$scope.putAsafeApply(function() {
 $scope.foo = 'bar';
});



Second Solution : It is simpler then the first one .You can use the $apply inside the $timeout function without delay.

$timeout(function(){
$scope.foo = 'bar';
})


 $timeout(callback) will wait until the current digest cycle (if any) is done, then execute your code, then run at the end a full $apply which will call $digest internally as explained earlier .



0 comments:

Post a Comment

...