[Fixed] Angular async validator stuck

Issue

I have quite a big reactive form, which I display on two tabs (each hidden/displayed by *ngIf). I’m passing necessary FormGroups / Arrays to those tabs through Inputs(). On the second tab there’s a list of items build on FormArray and some of it’s FormControls have async validators like this:

static ibanValidator(service: ValidationService) {
    return (control: AbstractControl) => {
        if (!control.value) {
            return of(null);
        }

        return control.valueChanges.pipe(
            debounceTime(500),
            distinctUntilChanged(),
            take(1),
            switchMap(v => {
                return service.validateIBAN(v)
            }),
            map((result: ValidationStatus) => {
                let e = null;
                if (result !== ValidationStatus.OK) {
                    e = {};
                    e[result.toLowerCase()] = 'IBAN'
                }
                return e;
            })
        );
    }
}

Everything works fine when I stay on the second tab (when I change the field value then the validator makes the async call and the status goes -> PENDING -> VALID.
But when I go back to the first tab then on the view creation angular calls:
_updateTreeValidity -> and for each field updateValueAndValidity which causes async validator to get called and I get PENDING status on fields with async validators since control doesnt changed
(_pendingChange = false).
How to handle this properly? Am I doing something wrong? Should I build each tab on separate Form?

Thanks for help!

Solution

No need to separate the form. And it has nothing to do with async validator.

I think the reason is that when switching to the first tab, you only removed the second form elements from the .html file, but you didn’t update Fromgroup in the .ts file. Because of that, the second form group validator gets called every time you make a change to the form.

Look at the simplified code below.

new FormGroup({
  firstFormGroup: new FormGroup(''),
  secondFormGroup: new FormGroup('', SomeValidator), // Remove this form control whenever you want to remove form tags from the thml page.
});

Leave a Reply

(*) Required, Your email will not be published