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.