Friday, July 22, 2016

Component Lifecycle: $doCheck (angular 1.5.x)

Since angular 1.5 components got introduced together with a well defined lifecycle. Currently their are 4 hooks you can use in angular 1 components:

  • $onInit
  • $onChanges
  • $postLink
  • $onDestroy

$doCheck

In version 1.5.8 a new hook is introduced: $doCheck. And this is the equivalent of the angular 2 ngDoCheck implementation. It also serves the same purpose as the $onChanges, allow to act on changes made to the bindable fields of a component. As $onChanges uses the built-in change detection of angular, the $doCheck implementation is totally up to you. The hook is called for every digest cycle of the component and just let’s you know you should check your bindings on changes so you can act on it.

Usage

One of the case this could be useful is when you make use of the one-way (<) binding for passing objects. In this case the $onChanges hook will be called if the reference of the object changes and not when fields on the object it self change. So currently you had 2 possibilities to solve this:

  1. Always make sure you are passing a new object. This way $onChanges hook will be called for every change because the reference of the object will change from time to time.
  2. Add a watch on the object to keep track of the changes. This also means you need to destroy and recreate the the watch every the reference of the object changes and you have an (unwanted) dependency on $scope inside your component.
   1: module.component("component",{
   2:     template: "<div>{{$ctrl.item}}</div>",
   3:     bindings: {
   4:         inputItem: "<item"
   5:     },
   6:     controller: ["$scope", function($scope){
   7:         var $ctrl = this;
   8:         var destroyWatch;
   9:         this.$onChanges = function(changeObj){
  10:             if(changeObj.inputItem){
  11:                 this.item = 
  12:                   angular.copy(changeObj.inputItem.currentValue);
  13:                 if(destroyWatch) destroyWatch();
  14:                 destroyWatch = $scope.watch(function (){ 
  15:                     return changeObj.inputItem.currentValue 
  16:                 }, function (){ /* handle Changes */ })
  17:             }
  18:         }
  19:     }
  20: }]);

The $doCheck hook now adds a third possibility to solve this issue. By checking manually if the object has changed you can act on it. This can be done by storing the passed value into a local variable, so it can be used in the next call as previous value for comparison.

   1: module.component("component",{
   2:     template: "<div>{{$ctrl.item}}</div>",
   3:     bindings: {
   4:         inputItem: "<item"
   5:     },
   6:     controller: function(){
   7:         var $ctrl = this;
   8:         var previousInputItem;
   9:         this.$doCheck = function(){
  10:             if(!angular.equals(previousInputItem, this.inputItem)){
  11:                 previousInputItem = this.inputItem;
  12:                 this.item = angular.copy(this.inputItem);
  13:             }
  14:         }
  15:     }
  16: });

Performance

Change detection in angular 1.x is done using digest cycles and for every cycle the $doCheck hook will be called. This means this will be called a lot. This is why you have the be careful using this hook so it doesn’t cause any performance issues. Also keep in mind that any change made to the model inside the $doCheck hook will trigger a new digest cycle. If implemented wrong this can result into a loop of digest cycles.

In angular 2 the change is implemented on a different (more performant) way and this will result in less calls of the ngDoCheck. It will also throw an error if you trigger changes outside of the component in prod mode.

Conclusion

The $doCheck hook gives you the ability to take the change detection of the bindable fields into your own hands. This makes it possible to detect changes inside objects and arrays without having to change the reference. Ditto for detecting changes in date objects.

The $onChanges and $doCheck hook can easily live side-by-side. The $doCheck hook doesn’t effect the $onChanges hook at all. Of course fields checked in the $doCheck hook no longer need to be handled in the $onChanges hook. In angular 2 it’s even recommended to not use these 2 hooks together.

25 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Nice to know this for binding changes but this bring me a question: In Angular 1.5 component, what's the correct way to implement a resize event so that we detect component width change? Any suggestion?

    ReplyDelete
  4. Hi, Got a question on your statement: "The hook is called for every digest cycle of the component" of when this doCheck actually gets executed.

    Does that mean it is isolated to just the bindings changes of the component?

    or the main $digest loop, ie any thing on the angular app that would fire off the $digest loop?

    ReplyDelete
  5. Wow! Thanks for this valuable information about new programming tools. It is not everyday that I have a possibility to see something like this. I like the way you write and presenting your ideas and views. I am hoping the same coolant works from you in future. Do not hesitate to use www.custom-paper-writing.org help for all new posts and be sure in their brilliant quality 24/7! You will be satisfied with the result.

    ReplyDelete
  6. Thank you for this article, I m looking this because I wanted to pass the same object between components changing only properties or methods while $onChanges hook is activated.

    ReplyDelete
  7. In this case, "$ctrl = this" is not necessary, right?

    ReplyDelete
  8. Just wish to say your article is as astounding. The clearness in your
    submit is just excellent and i can suppose you’re knowledgeable in this subject.
    Well along with your permission allow me to take hold of your RSS feed to stay up
    to date with drawing close post. Thanks a million and
    please carry on the rewarding work.
    Check Mine: AngularJS Training in Chennai

    ReplyDelete
  9. I found this blog very useful. I also recommend you visit this page to know how to spy on facebook.

    ReplyDelete
  10. I really to read your blog.You provide valuable information in this blog.This information can help lot of fresher to learn Angularjs. Thanks for sharing.keep sharing more blogs.


    Angularjs Online Training

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Good Explanation for Component Lifecycle$doCheck (angular 1.5.x), Please give some example in AngularJs 4, I want to Learn AngularJs 4

    ReplyDelete
  13. In angular 2 the change is implemented on a different (more performant) way and this will result in less calls of the ngDoCheck. It will also throw an error if you trigger changes outside of the component in prod mode. Essay Help Websites

    ReplyDelete
  14. Very interesting and good article, it is very useful to me… keep rocks.. thanks for sharing your valuable time and views….No.1 Software Testing Training Institute in Chennai | Best Selenium Training Institute in Chennai | ISTQB Certification Center in Velachery

    ReplyDelete
  15. Interesting post! This is really helpful for me. I like it! Thanks for sharing!
    Android Project Center in Chennai | Android Project Center in Velachery

    ReplyDelete
  16. Thanks for the excellent tutorials. Can you please update the same for the latest versions of Angular?

    Thanks

    ReplyDelete
  17. thanks for this code, I was just working on the project, I passed it a couple of hours ago, thank you very much, very much helped

    ReplyDelete
  18. Well Said, you have furnished the right information that will be useful to anyone at all time. Thanks for sharing your Ideas.
    Angularjs course in chennai

    ReplyDelete
  19. Yeah I definitely agree with your opinion, would like to read this blog regularly to get more important stuff from here...
    Best Online Software Training Institute | Angular 6 Training

    ReplyDelete

  20. Really cool post, highly informative and professionally written and I am glad to be a visitor of this perfect blog, thank you for this rare info!
    Angularjs course in chennai

    ReplyDelete
  21. This comment has been removed by a blog administrator.

    ReplyDelete
  22. thanks for sharing this help article. we are providing in Boston escorts services. we Skissr are provide best Boston female escorts.

    ReplyDelete