Angular 7: пользовательский асинхронный валидатор - PullRequest
0 голосов
/ 21 марта 2019

Я пытаюсь создать собственный асинхронный валидатор для моей регистрационной формы, где он проверяет, существует ли уже электронное письмо.Бэкэнд возвращает 404, если электронная почта не существует, и 200, если она существует (не может изменить этот старый код).

Я нашел пару учебных пособий, но не нашел ни одного, использующего последнюю библиотеку rxjs.Я создал этот класс проверки:

export class UniqueEmailValidator {
    static createValidator(httpClient: HttpClient, degree: number, wlId: number) {
        return (control: AbstractControl) => {
            return httpClient.get(`${url}?degree=${degree}&email=${control.value}&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 Ответ

0 голосов
/ 21 марта 2019

Разобрался через некоторое время и проведу дополнительные исследования.

Класс проверки:

@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}&email=${email}&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 в качестве поставщика в модуль и внедрил его в конструктор этого компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...