Reputation: 400
I'm trying to create custom validator function in reactive form. Code:
form.component.ts
...
form = new FormGroup({
username: new FormControl('', [
Validators.required,
Validators.minLength(3)
],
UsernameService.isUnique
)
});
...
username.service.ts
...
static isUnique(control: AbstractControl): Promise<ValidationErrors | null> {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ notUnique: true });
}, 2000);
});
}
...
There is an error shown while hovering on UsernameService.isUnique
-
"Argument type (control: AbstractControl) => Promise< ValidationErrors | null > is not assignable to parameter type AsyncValidatorFn | AsyncValidatorFn[] | null"
Why this error exists? According to documentation (https://angular.io/api/forms/AsyncValidatorFn) I used proper call signature of AsyncValidatorFn.
Upvotes: 5
Views: 5528
Reputation: 1781
The solution is actually very simple --
add "as AsyncValidatorFn" behind "UsernameService.isUnique":
UsernameService.isUnique as AsyncValidatorFn
or add AsyncValidatorFn before it within "<>":
<AsyncValidatorFn>UsernameService.isUnique
Of course, AsyncValidatorFn needs to be imported:
import { AsyncValidatorFn } from '@angular/forms';
Example in practice:
The following picture shows that there is an error WITHOUT "as AsyncValidatorFn":
The error message is about the same:
Argument of type '(control: FormControl) =>
Promise<any> | Observable<any>' is not assignable to
parameter of type 'AsyncValidatorFn | AsyncValidatorFn[]'
The following shows that the error DISAPPEARED after "as AsyncValidatorFn" is added (behind):
or (before):
The following is the "forbiddenEmails" function:
Actually, you can solve many similar problems in the same way.
Upvotes: 9
Reputation: 549
Here is a good tutorial you can try https://www.netjstech.com/2020/11/custom-async-validator-angular-reactive-form.html
Upvotes: 0
Reputation: 400
There was a typescript problem - importing bad type(?) of Promise
, I had to add install this module
npm i --save bluebird
and use this as Promise import in component:
import * as Promise from 'bluebird';
Upvotes: -2