Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5 ngOnChanges fires only once in child component

I have a child component that contains complex input (some chart data). I am sending this chart data from the parent component through the @Input() decorator in Angular 5 after getting API response. So, I need to sync the chart according with the API response every time it gets changed on the parent component, hence, the OnChange Lifecyle. But unfortunately, I am not able to get this to work properly. I tried with setting a dummy input field with basic number type and increment it but in vain. Here's my implementation:

Child chart component:

export class ChartComponent implements OnInit, OnChanges {

  @Input() chartData;
  @Input() triggerChart;

  ngOnChanges(changes: SimpleChanges) {
    console.log(changes);
  }

}

Parent component html:

<app-chart [chartData]="chartData" [triggerChart]="triggerChartData"></app-chart>
<input [(ngModel)]="triggerChartData" type="hidden">

Parent component:

this.chartService.getChartData(params).subscribe(res => {
  this.chartData = res;
  this.triggerChartData++;
});

PS: The ngOnChanges as the title indicates only fires once when the component initializes with undefined values.

like image 579
Mehdi Benmoha Avatar asked Jan 15 '18 13:01

Mehdi Benmoha


1 Answers

Thanks to @HoangDucNguyen, here's the working code:

this.chartService.getChartData(params).subscribe(res => {
  this.chartData = res;
  this.changeDetectorRef.detectChanges();
});

Of course you will need to import the ChangeDetectorRef class from @angular/core and inject it in your constructor.

Explanation:
When variables are changed outside of the angular context (in here: it's the rxJs context), Angular isn't able to detect changes on the variables. So, you need to manually fire the detect changes angular method.

Official doc: https://angular.io/api/core/ChangeDetectorRef

like image 191
Mehdi Benmoha Avatar answered Sep 28 '22 00:09

Mehdi Benmoha