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

5

63

Difference between them seems to be very confusing to me. What is difference between them and exactly when they are called

Fiftieth answered 28/7, 2016 at 7:32 Comment(0)
O
72
  • 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.

Octillion answered 28/7, 2016 at 7:34 Comment(9)
actually i am confused by the term "change detection runs", when angular checks for change detectionFiftieth
Angular uses zone.js and patches all kinds of async apis addEventListener, setTimeout, ... Every time an event handler or some other async code is completed or when change detection is invoked explicitely by some code, Angular2 runs change detection. This is when ngDoCheck is called. ngOnChanges is only called when change detection detects a change that requires an input to be updated.Merat
ngDocheck called every time when there is change detection cycle runs while ngOnChange only fire when there is a change in bound model property in componentFarewell
@RajBahadurSingh isn't this exactly what my answer says?Merat
Actually, the answer could be much better if you would mention that ngOnChanges only triggers when the actual instance of the object changesPappano
@YannicHamann I assume you mean that Angular does not recognize a change if only a property of a bound value was changed (instead of the new value being a different instance).Merat
Yeah exactly, doesn't that mean (maybe I am confusing terminology) that the part of the change management for angular that invokes ngOnChanges() only detects if the bound value changes its object instance?Pappano
Yes that is what it means. My answer follows on that. When Angular recognizes the value has changed, it updates the binding and that causes ngOnChanges to be called.Merat
angular folks need to add these statements. ThanksDisequilibrium
U
44

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.

Ulani answered 29/12, 2016 at 13:41 Comment(0)
J
31

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

Jovitta answered 14/4, 2017 at 11:32 Comment(0)
O
4

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.

Orgulous answered 27/3, 2019 at 16:1 Comment(1)
What's ngOnCheck , I do not see it mentioned in the official Angular documentation, angular.io/guide/lifecycle-hooks#lifecycle-event-sequence ?Unmuzzle
F
1

ngDoCheck(): will be called every time a change detection system detects a change ngOnChanges(): will be called only when a child component receives a value from parent component using @input decorator.

Floss answered 28/8, 2023 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.