Angular onPush does not update child property from parent Angular onPush does not update child property from parent angular angular

Angular onPush does not update child property from parent


The problem is related to this issue reported on GitHub. It occurs when:

  • The OnPush change detection strategy is used for the child component
  • An input property of the child is changed directly in the parent component code instead of being data-bound in the parent component template

The explanation given by AngularInDepth.com:

The compiler doesn't have a way to generate necessary information for checking the bindings since it can't find these bindings in the template. OnPush is tightly bound to the input bindings. What's important is that Angular checks the second part of the binding (prop in the example below), not the first (i):

<child [i]="prop">

to determine whether the change detection should be run for the child component. And it does so when checking parent component. If you don't show the compiler what parent property should be used to update child input binding, it can't generate necessary information used when checking the parent. So inspecting @Input on child components isn't enough. That's the mechanism of change detection and I don't see any way it could be changed.

One workaround suggested by yurzui in the discussion is to call ChangeDetectorRef.markForCheck in the child component after setting the text property, as shown in this stackblitz. As a matter of fact, it works without calling ChangeDetectorRef.detectChanges in the parent component.

export class ChildComponent {  private _text = '';  @Input()  get text() {    return this._text;  }  set text(val) {    if (this._text !== val) {      this.cdRef.markForCheck();    }    this._text = val;  }  constructor(public host: ElementRef, private cdRef: ChangeDetectorRef) { }}