#angular #validation #asynchronous #rxjs #angular7
#angular #проверка #асинхронный #rxjs #angular7
Вопрос:
Я пытаюсь создать пользовательский асинхронный валидатор для моей регистрационной формы, где он проверяет, существует ли уже электронное письмо. Серверная часть возвращает 404, если электронное письмо не существует, и 200, если оно существует (не удается изменить этот старый код).
Я нашел пару руководств, но не нашел ни одного, использующего последнюю версию библиотеки rxjs. Я создал этот класс проверки:
export class UniqueEmailValidator {
static createValidator(httpClient: HttpClient, degree: number, wlId: number) {
return (control: AbstractControl) => {
return httpClient.get(`${url}?degree=${degree}amp;email=${control.value}amp;wl_id=${wlId}`)
.pipe(
map(
(response: Response) => {
return response.status === 404 ? null : { emailNotUnique: true };
}
)
);
};
}
}
и в моем ts-файле, создающем форму, я использую это
this.registerForm = this.fb.group({
email: ['', [Validators.required, Validators.email], UniqueEmailValidator.createValidator(
this.httpClient, this.wlService.wl.degree, this.wlService.wl.id)],
Вызов xhr выполняется и возвращается правильно, но управление формой электронной почты остается ожидающим. Есть идеи о том, что я сделал не так?
Ответ №1:
Понял это через некоторое время и после дополнительных исследований.
Класс проверки:
@Injectable()
export class UniqueEmailValidator {
constructor(private http: HttpClient) {}
searchEmail(email: string, degree: number, wlId: number) {
return timer(1000)
.pipe(
switchMap(() => {
// Check if email is unique
return this.http.get<any>(`${url}?degree=${degree}amp;email=${email}amp;wl_id=${wlId}`);
})
);
}
createValidator(degree: number, wlId: number): AsyncValidatorFn {
return (control: AbstractControl): Observable<{ [key: string]: any } | null> => {
return this.searchEmail(control.value, degree, wlId)
.pipe(
map(
(response: Response) => {
return null;
},
),
catchError(
(err: any) => {
return err.status === 404 ? of(null) : of({ emailNotUnique: true });
},
),
);
};
}
}
Не уверен, можно ли изменить таймер, но я нашел его в статье, и он отлично работает. Хотелось бы получить подтверждение по этому поводу.
По сути, я выполняю ошибку catchError, поскольку ответ от серверной части возвращает 404 и снова возвращает наблюдаемое значение из ошибки catchError.
Затем при создании формы я делаю:
this.registerForm = this.fb.group({
email: ['', [Validators.required, Validators.email], this.uniqueEmailValidator.createValidator(
this.wlService.wl.degree, this.wlService.wl.id
)],
И я добавил UniqueEmailValidator в качестве поставщика в модуле и внедрил в этот конструктор компонента.
Комментарии:
1. У меня ошибка. «это» не определено в классе «UniqueEmailValidator».