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 :)