Real UseCases for ngDoCheck (Angular9)

1.8k Views Asked by At

I am a beginner in Angular & learning by myself and i have stucked in ngDoCheck life cycle method

According to Documentation:
Detect and act upon changes that Angular can't or won't detect on its own.

Parent Component:

user={
   name:"xxx"
}

update(){
  this.user.name="yyy"
}

Parent view:

<button (click)="update">update</button>
<child-comp [inputprop]="user"></child-comp>

Child Component

ngDoCheck(){
console.log(this.inputprop);
}

As Far as I know,using this life cycle method to get the latest changes in deeper level that ngOnChanges can't detected the input property changes in deeper level.

In Simple words,ngOnChanges will detect the property changes only the reference of property gets changed.

In Above Example ngDocheck lifecycle method doesn't done anything to get the latest changes of property. But instead, change detection helps to get the latest changes in deeper level

I wants to know the exact use case for using the ngDoCheck lifecycle method.

2

There are 2 best solutions below

3
On BEST ANSWER

Your child component change detector may have the following strategies

  1. default
  2. onPush

In the default strategy, CD runs for any change in @Input() decorated properties

In the onPush strategy, CD runs when you pass a new object (reference) to the @Input decorated properties.

Regardless of the strategy, CD always run in the following scenarios,

  1. An event such as click, submit gets fired
  2. XHR call to work with an API
  3. Asynchronous JavaScript functions such assetTimeOut() or setInterval() gets executed

Keep in mind that Angular CD can be visualized as a directed tree, which means all components can be seen as a node in a tree and Angular always runs CD from root node to the bottom of the tree.

Anguular Componnet Tree

Even there is an event fired in CC-121, Angular would run CD from the root component to the bottom. However, running of CD would stop at the node where strategy is set to onPush and you are not passing a new object in one of the @Input decorated properties.

So now you understand a bit about when and how CD runs, ngDoCheck() life cycle gets executed each time CD runs for the component.

I hope it helps.

Thanks

1
On

i see that you are confused between two lifecycle hooks.

In Angular , we can perform change detection using two different lifecycle hooks :

the ngOnchanges lifecycle hook and the ngDoCheck lifecycle hook.

But in some cases, the ngOnChanges is not enough to detect all changes because it uses the property reference to check the difference, so it can’t detect the changes if you update the object property.

Meanwhile, the ngDoCheck lifecycle hook allows us to perform our custom change detection so we can bypass the ngOnChange lifecycle hook limitations.

For example, if you pass a User Object from the parent component then you update the age or the username property of the User object, in this case the Angular will not fire the event to dispatch the ngOnChange callback. Because it has the same reference of the User object.

So you can resolve this problem by using ngDoCheck lifecycle hook.

by using ngDoCheck , we can use more advanced tools like key-value differs and iterable differs services to perform custom change detections.

check this little example :

  //child-component.ts
import {Component, DoCheck, Input, KeyValueDiffers, OnInit} from "@angular/core";

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
})
export class ChildComponent implements OnInit, DoCheck {

  @Input() user: any;

  changelogList: Array<string> = [];

  differ: any;

  constructor(private differs: KeyValueDiffers) {
  }

  ngOnInit() {
    this.differ = this.differs.find(this.user).create();
  }


  ngDoCheck() {
    const userChanges = this.differ.diff(this.user);
    if (userChanges) {
      userChanges.forEachChangedItem((changeRecord: any) => {
        this.changelogList.push('item changed : ' + changeRecord.key + ' ' + JSON.stringify(changeRecord.currentValue))
      });
      userChanges.forEachAddedItem((changeRecord: any) => {
        this.changelogList.push('item added : ' + changeRecord.key + ' ' + JSON.stringify(changeRecord.currentValue))
      });
    }
  }
}

the differ method inside the ngDoCheck returns un object that provides multiples advanced methods such as

forEachItem, forEachPreviousItem, forEachChangedItem, forEachAddedItem, forEachRemovedItem.