0

I have a FormGroup array of rates namely ratesMainArray being @Input from a parent to my child component. I am filtering it in ngOnChanges by its special or normal key value every time its length in the parent component changes and storing the length value of the filtered array in two local properties, specialRates and normalRates which are of course of type number. I need to listen to that length value changes, but ngOnChanges only reacts to the parent array changes. I have started using ngDoCheck which actually detects the filtered arrays value changes, but I am receiving the error Error trying to diff '2'. Only maps and objects are allowed when I try to react to the filtered array length.

This is a simplified version of the code:

...
@Input() ratesMainArray: FormGroup[];
specialRates: number;
normalRates: number;
differ: any;

constructor(private differs: KeyValueDiffers) {
    this.differ = differs.find({}).create();
  }

ngDoCheck() {
    const changes = this.differ.diff(this.specialRates);
      if (changes) {
         changes.forEachAddedItem(r => console.log('added ' + r.currentValue));
                   }
}

async ngOnChanges(changes: SimpleChanges) {

    if ((this.ratesMainArray && this.ratesMainArray.length) 
         && (changes && changes.ratesMainArray && changes.ratesMainArray.currentValue.length)) {

this.specialRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === true).length;
this.normalRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === false).length;

}

// ideally, I would like to do something like this:
// if (this.specialRates.valueChanges or changes.specialRates.currentValue) {
// do somthing
// } else {
// do something else
// }

}

I don't necessarily need to use ngDoCheck, but since it was detecting the filtered array change I thought it was the way to go. Just for clarity, I also tried using private cd: ChangeDetectorRef and this.cd.detectChanges(); without luck before trying ngDoCheck.

Thanks for you help!!

mike87
  • 309
  • 2
  • 11

1 Answers1

0

You can use 'set' to analyze the data that you receives in the @Input()

specialRates: number;
normalRates: number;
differ: any;
private _ratesMainArray: FormGroup[];
get ratesMainArray(): FormGroup[] {
   return this._ratesMainArray;
}
@Input() set ratesMainArray(value: FormGroup[]){
    if(value) {
      this._ratesMainArray = value;
this.specialRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === true).length;
this.normalRates= this.ratesMainArray.filter(t => t.controls.isSpecialRate.value === false).length;
    }
}

constructor(private differs: KeyValueDiffers) {
   this.differ = differs.find({}).create();
}

Here you have another example of get/set in @Input(): Angular2 @Input to a property with get/set

German Quinteros
  • 1,870
  • 9
  • 33
  • Hi, and thanks for helping. I edited my code with `set` and `get`, now I'm doing my filtering in the `@Input()` as you pointed out but still I am not able to detect changes to them in `ngOnChanges` or `ngDoCheck`. I mean, am I supposed to? – mike87 Nov 13 '19 at 13:36
  • No, now every time that the @Input() changes, you have the new values for your properties. I have just updated my answer – German Quinteros Nov 13 '19 at 14:02
  • I can still only see the `simpleChanges` related to the length of my `ratesMainArray` unfortunately... and `ngDoCheck` shows the same `[ object Object ]`. – mike87 Nov 13 '19 at 17:24