Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does ngOnChanges take time. Is it asynchronous?

I am using angular 9+ and i am little confused of the behavior of ngOnChanges life cycle.

What I am trying to do

I have a asynchrounous operation which sets a value (Object type) to the child component using @Input() decorator. The code is as below. (Stackblitz Here)

parent.ts

import { AfterViewInit, Component, VERSION, ViewChild } from '@angular/core';
import { ChildComponent } from './child/child.component';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild(ChildComponent) childComponent: ChildComponent;
  data = { value: null };

  constructor() {}

  ngAfterViewInit() {
    const foo = of([1])
      .pipe(delay(500))
      .subscribe(subscriber => {
        this.data = { value: 123 };
        this.childComponent.printState();
      });
  }
}

Parent.Html

<app-child [data]="data"></app-child>

Child Component

    import { Component, Input, OnChanges } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnChanges {
  @Input() data = null;

  constructor() {}

  ngOnChanges(changes) {
    console.log('ngOnChanges');
  }

  printState() {
    console.log('printState');
    console.log(this.data.value);
  }
}

What i am trying to is , as soon as i change the value, i am trying to print the value of the set value by using a view child reference as shown above.

Ideally the sequence should have been

ngOnChanges // initial value
ngOnChanges // after value set
printState // after calling printState()

but i see

ngOnChanges 
printState 
ngOnChanges

in the console which is pretty consfusing. Why is ngOnChanges nor fired immediately. Why is it taking time. Can someone explain.

Thanks and stay safe :)

like image 627
Vikhyath Maiya Avatar asked Jan 19 '26 21:01

Vikhyath Maiya


1 Answers

When you update any variable bound to @Input() as you are doing in ngAfterViewInit of AppComponent , the change detection will be scheduled by Angular to run just before view rendering and not immediately after assignment.

Hence, the code in ngAfterViewInit will execute first, and code in ngOnChanges will be invoked by Angular in next tick.

Yes, in summary, change detection is asynchronous.

like image 154
Wand Maker Avatar answered Jan 21 '26 10:01

Wand Maker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!