I am setting a value from the parent component and changing it immediately. In the child component, change detection executes only once.
Parent's code: HTML
<h1>Parent Component</h1>
<p>Contents of the parent component</p>
<button (click)='parentClickEvt()'>Parent Button</button>
<child [message]="msg" (informParent)="parentWillTakeAction($event)"></child>
Parent's code: TS
export class ParentComponent {
msg: string="testing";
parentWillTakeAction(message) {
this.messageFromChild = message;
}
parentClickEvt() {
this.msg = "Message from parent to child";
this.msg = "India";
this.msg = "India, ASIA";
this.msg = "JAPAN";
this.msg = "JAPAN, ASIA";
}
}
Child's code: TS
export class ChildComponent implements OnInit {
@Input() message: string;
@Output() informParent = new EventEmitter();
ngOnChanges(simpleChanges: SimpleChanges) {
console.log(simpleChanges.message.currentValue)
}
}
Executing parentClickEvt method from parent is changing msg value 4 times. In child component, ngOnChanges is supposed to execute 4 times. But it is only executing once with the latest value.
Please suggest how ngOnChanges should execute according to all changes
First implement OnChanges on child component.
Change detection is not working because you are changing value of msg without letting previous change detection to be completed.
I would suggest to change the approach of this rapid reassignment of values if possible, However I have a workaround. see if you can use it.
import { Component, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
messageFromChild: string = '';
msg: string = 'testing';
constructor(private changeDetectorRef: ChangeDetectorRef) {}
parentWillTakeAction(message: any) {
this.messageFromChild = message;
}
async parentClickEvt() {
this.msg = 'Message from parent to child';
await this.detectChanges();
this.msg = 'India';
await this.detectChanges();
this.msg = 'India, ASIA';
await this.detectChanges();
this.msg = 'JAPAN';
await this.detectChanges();
this.msg = 'JAPAN, ASIA';
}
detectChanges(): Promise<void> {
return new Promise((resolve) => {
this.changeDetectorRef.detectChanges();
resolve();
});
}
}
By this way you will be able to catch change in ngOnChanges of child component.