Search code examples
angularangular-lifecycle-hooksngonchangesangular2-docheck

ngOnchanges and DoCheck in angular


When study the difference between ngOnChanges and DoCheck in Angular, I see something I cant explain and need your help.

Basically, I understand that ngOnChanges can't recognize the change of array or object and DoCheck can. I created the stackblitz here: https://stackblitz.com/edit/angular-ivy-sbyzya?file=src/app/app.component.html

In app.component.html

  • If you comment line 2, so only component which ngOnChanges run, the data didn't sort when click add or edit. It 's right because OnChange can't detect the change of array @Input.
<data-table-onchange [data]="numbers"></data-table-onchange>
<!-- <data-table-docheck [data]="numbers"></data-table-docheck> -->
  • If you comment line 1, so only component which DoCheck run, the data sort when click add or edit. It 's right because DoCheck can detect the change of array @Input.
<!--<data-table-onchange [data]="numbers"></data-table-onchange> -->
 <data-table-docheck [data]="numbers"></data-table-docheck>
  • But if you let both child component run, when click add or edit, data in both child component is sorted. It seems weird to me because I dont understand why the DataTableOnchangeComponent can run sort function. I put sort in ngOnChanges, ngOnChanges didn't trigger when click add or edit, but somehow the data still get sorted.
<data-table-onchange [data]="numbers"></data-table-onchange>
<data-table-docheck [data]="numbers"></data-table-docheck>

Solution

  • The reason both the tables are sorting the numbers, when you uncomment both the lines is because, when the DoCheck initiates the sorting, the numbers array is actually getting sorted, and it's the same array that shows up in both the components. Javascript's Pass By Reference in play.

    To see the difference, try setting 2 different arrays to both the component, and you should see that the array in the OnChanges component does not sort.

    <data-table-onchange [data]="numbers"></data-table-onchange>
    <data-table-docheck [data]="numbers2"></data-table-docheck>
    

    in TS

    public numbers: number[] = [5, 69, 9];
    public numbers2: number[] = [5, 69, 9];
    
    public add(): void {
      const random: number = Math.floor(Math.random() * 100);
      this.numbers.push(random);
      this.numbers2.push(random);
    }