@Input does not work with OnPush change detection

Viewed 405

page.html

<app-parcel-delivery-cost-promo [parcelDeliveryCost]="parcelDeliveryCost">
  </app-parcel-delivery-cost-promo>

page.ts

changeDetection: ChangeDetectionStrategy.OnPush,

parcelDeliveryCost: Partial<ParcelDeliveryCostModel>;

  ngOnInit(): void {
     this.translateService.get(['Client.Parcel-Delivery-Cost']).subscribe(res => {

      this.parcelDeliveryCost = {
        title: res['Client.Parcel-Delivery-Cost'],
        description: res['Client.Parcel-Picked-Up-From-The-Location-And-Delivered-To-You'],
        cost: environment.parcelDeliveryCost
      };
    });
  }

component.ts

 changeDetection: ChangeDetectionStrategy.OnPush,

export class ParcelDeliveryCostPromoComponent implements OnInit {

  @Input() parcelDeliveryCost: ParcelDeliveryCostModel;

  constructor() { }

  ngOnInit(): void { }

}

componet.html

<ion-grid>
  <ion-row>
    <ion-col size="12" >
      <h5 class="font-bold margin-top-bottom-5">{{parcelDeliveryCost?.title}}</h5>
    </ion-col>
    <ion-col size="12">
      <div class="color-medium">{{parcelDeliveryCost?.description}}</div>
    </ion-col>
    <ion-col size="12">
      <h4 class="margin-top-bottom-5 text-line-through">{{parcelDeliveryCost?.cost}}</h4>
    </ion-col>

  </ion-row>
</ion-grid>

Q: Could you tell me why @Input does not work with OnPush change detection? Where is the issue of this code? i.e. I can't see the app-parcel-delivery-cost-promo component. But if I'll change something on the page then it shows.

2 Answers

Input works fine. Subscription in ngOnInit with OnPush doesn't run change detection. You need to do one of following:

  • run change detector manually in subscription
  • use async pipe instead of .subscribe() (async pipe runs markForCheck)
  • turn off OnPush strategy

Try this

 this.parcelDeliveryCost = Object.assign({},{
        title: res['Client.Parcel-Delivery-Cost'],
        description: res['Client.Parcel-Picked-Up-From-The-Location-And-Delivered-To-You'],
        cost: environment.parcelDeliveryCost
      });

As if the reference of a object is updated angular will run change detection.

Related