Reputation: 2237
so I am creating a validator which checks if the username is already taken.
I have the following Custom validator definition:
import { AbstractControl } from '@angular/forms';
import { AccountApi } from '../../api/service/account.api';
import { Injectable } from '@angular/core';
import { switchMap, mapTo, catchError } from 'rxjs/operators';
import { of, timer } from 'rxjs';
@Injectable()
export class UsernameValidator {
constructor(private api: AccountApi) {
}
exists(control: AbstractControl) {
// this.api.checkUsernameIfExisting(control.value).subscribe((existing) => {
// control.setErrors({ exists: existing });
// });
// return null;
return timer(100).pipe(
switchMap(() => this.api.checkUsernameIfExisting(control.value).pipe(
// Successful response, set validator to null
mapTo(null),
// Set error object on error response
catchError(() => of({ exists: true }))
)
)
);
}
}
This is how I used it:
username: ['', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(30),
this.usernameValidator.exists.bind(this.usernameValidator)
]],
My question is, why does the call on my API doesn't get triggered? I checked if the form is calling exists() and it calls it.
Thanks!
Upvotes: 2
Views: 2529
Reputation: 1
The async validator must be added outside of the formcontrol constructor.
Here is another example.
export class AppComponent {
myControl = new FormControl('');
constructor(private http: HttpClient) {
this.myControl.addAsyncValidators(this.validateStockSymbol);
}
Upvotes: 0
Reputation: 214017
Async validators should go after sync validators.
So I would try something like this:
username: ['', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(30),
],
this.usernameValidator.exists.bind(this.usernameValidator)
],
Upvotes: 5