Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between OnChanges and DoCheck in Angular 2?

Tags:

angular

People also ask

What is DoCheck in Angular?

A callback method that performs change-detection, invoked after the default change-detector runs. See KeyValueDiffers and IterableDiffers for implementing custom change checking for collections.

Is ngOnChanges called before ngOnInit?

ngOnChanges( ) — It is called before ngOnInit( ) and whenever one or more data-bound input properties change. It detects simple changes in the property values. ngOnInit( ) — It initializes the directive/component after Angular displays the data-bound properties and is called once after ngOnChanges( ).

How do you use ngOnChanges?

When should you use ngOnChanges? Use ngOnChanges whenever you want to detect changes from a variable decorated by @Input. Remember that only changes from the parent component will trigger this function. Also remember that changes from the parent still update the child value even without implementing ngOnChanges.

What is ngOnChanges?

ngOnChanges()link A callback method that is invoked immediately after the default change detector has checked data-bound properties if at least one has changed, and before the view and content children are checked.


  • ngOnChanges() (OnChanges) is called when a value bound to an input has changed so you can run custom code when an input has changed.

  • ngDoCheck() (DoCheck) is called when change detection runs so you can implement your custom change detection action.


I was playing with these two and found some interesting stuff that worth sharing :

ngDoCheck():

This will get called every time one of Zone hooks get called,

How?

Angular2 uses NgZone, which as @Gunter said as well, has monkey patched all the async events inside the browser, you can think of it like ;

var originalTimeout = window.setTimeout;
window.setTimeout = function(callback,time) {
    originalTimeout(callback,time);

    // notify Angular that a setTimeout is fired
    // e.g run ngDoCheck() for components
}

So every time you run setTimeout, you're actually calling above function which is monkey patched the original setTimeout.

Disclaimer: Above code is completely abstract and in Zonejs you're not gonna find it, but I just wanted to somehow show what it means when they say "Zone has patched all the async functions and have hooks in them";

Anyways, so every time you run a setTimeout (or any other async function), when it's finished, ngDoCheck will be called.

So it means angular just checks to see if there has been a change in the model or any of the @inputs or not.

When this is handy?

ngDoCheck becomes handy if your component's ChangeDetectionStrategy is OnPush, meaning that it's only gonna update the view if any of the @Inputs references has been changed.

Which there are some cases that you want to use OnPush but you want to do some manual updating on every check.

Check out this plunker .

You'll find that even if the ChangeDetectionStrategy of the on-push-test component is OnPush, when we click on mutate food and that mutates the foods list, I'll run the markForCheck inside the ngDoCheck and update the view after a dummy if condition.

So this means, this function will get called A LOT !!! so be careful what you're putting inside it.

So in short :

ngDoCheck : this function will get called every single time an event has fired in the app that may cause a change, but not necessarily is considered a change.


ngOnChanges

This will only and only get called if there has been a reference change in any of the @Inputs bindings, regardless of the ChangeDetectionStrategy of the component.

So if we mutate foods array like this :

this.foods.push({value: 'steak-3', viewValue: 'Fish'});

The ngOnChanges will not get called, but if we update the reference like this:

this.foods = [{value: 'steak-3', viewValue: 'Fish'}];

It'll get called.


First of all Kudos to the above answers. I am adding a use-case for both of the functions which I have faced personally.

ngOnChanges() (OnChanges): to detect changes for variables passed by value

ngDoCheck() (DoCheck) : to detect changes for variable passed by reference such as arrays, which are not detected by ngOnChanges() as the old value and the new value have the same reference


ngDoCheck is called on the child component when the parent component is being checked.
ngOnChanges is triggered every time when the Angular detected a change to the data-bound input property.
ngOnChanges does not fire when the input property is an array/object because Angular uses dirty checking to compare the properties.
ngDoCheck does fire when the input property is an array/object like customer class etc.