Your inner formArray is valid if the quotes sum a value that belong to the formGroup. So you need validate the formGroup, not the formArray
this.data.sessionList.forEach((x) => {
this.sessionListFormArr.push(
this.fb.group(
{
sessionId: x.sessionId,
totalQuota: x.totalQuota,
enrolTypeList: this.setenrolTypeList(x),
},
{ validator: this.checkTotlalQuotaValidator() }
)
);
});
And the custom validator is simply
checkTotlalQuotaValidator(form: FormGroup) {
const totalQuota: number = +form.get('totalQuota').value;
const subQuota:any[]= form.get('enrolTypeList').value;
const sumSubquota=subQuota.reduce((a,b)=>a+b.subQuota,0)
return sumSubquota==totalQuota?null:{error:'should meet the sum'}
}
Now you can use this error in your .html like
<div class="col-lg-3 mb-1" style="color:blue">
Total Quota: {{sessionListFormArr.controls[i].errors|json}}
</div>
And
<button [disabled]="sessionListessionDynamicForm.invalid"
(click)="checkTotal()">save</button>
Well, a Validator is executed by defect each time the FormControl or the FormGroup change, so Angular execute severals time the function. You can indicate that this is executed only on submit -in this case you can not use [disabled] in the button-
{ validators: [this.checkTotlalQuotaValidator],updateOn:'submit' }
NOTE: You should use form -no <div> when you has a Form and the button should be inside the "form"