I need to compare the amount
from the applied_amount
. However they are on different controls but they are on the same formgroup. How should i check if the "amount" is greater than the "applied_amount"? Here's the code below.
this.reportForm = this.fb.group({
employee_id: [null, Validators.required],
outlet_id: [null, Validators.required],
grand_total: new FormControl({value: null, disabled: true}, Validators.required),
rows: this.fb.array([]),
applied_amount: [null, Validators.required],
});
initGroup() {
let rows = this.reportForm.get('rows') as FormArray;
rows.push(this.fb.group({
expense_account: ['', Validators.required],
description: ['', Validators.required],
amount: ['', Validators.required],
},{validator: this.customValidator(rows)}))
}
customValidator(group: any) {
if ((group.controls.amount.value > group.parent.parent.controls.applied_amount.value)) {
return { out1: true }
}
return null;
}
First of all you shouldn't call method customValidator
method as mentioned @Boris Lobanov
It says it cannot read parent of undefined
That is because when angular creates FormGroup
through FormBuilder::group
it also calls validators but current group doesn't have parent yet. The parent will be set only after FormArray::push
.
So the solution could look like:
validator: this.customValidator
...
customValidator(group: any) {
if (!group.parent ) {
return;
}
...
I also fire validation for all rows when applied_amount
is changed.
html
<input type="number" formControlName="applied_amount" (ngModelChange)="validateAllRows()">
ts
validateAllRows() {
const rows = this.reportForm.get('rows') as FormArray;
rows.controls.forEach(group => {
group.updateValueAndValidity();
})
}
Another solution is almost the same like yours:
validator: this.customValidator.bind(rows)
...
customValidator(this: FormArray, group: any) {
if (group.controls.amount.value > this.parent.controls['applied_amount'].value) {
return { out1: true }
}
return null;
}
Here I use Function.prototype.bind
method to pass FormArray
directly to your validator.