@nekritik

Angular 8: при попытке сделать инъекцию валидатора в конструктор компонента, Angular редиректит меня на главную, не выводя никаких ошибок. Почему?

Проблема, судя по всему, совсем простая но я не могу найти решения. Есть компонент registration-page.component.ts, который просто выводит форму с одним полем - email
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {EmailExistsValidator} from '../shared/services/my.validators';

@Component({
  selector: 'app-registration-page',
  templateUrl: './registration-page.component.html',
  styleUrls: ['./registration-page.component.css']
})
export class RegistrationPageComponent implements OnInit {

  form: FormGroup
  constructor() { }

  ngOnInit() {
    this.form = new FormGroup(
      {
        email: new FormControl(null, [Validators.required, /*this.emailExistsValidator.validate.bind(this.emailExistsValidator)*/])
      });
  }

}


Роутинг настроен таким образом, чтобы при перехода на localhost:4200/registration отображалась форма с полем email.
Для моего пока-что единственного поля, email, мне нужно сделать самописный валидатор, который будет проверять нет ли уже зарегистрированного пользователя с таким адресом. Валидатор я писал по этому и этому примерам из официального репозитория ангуляра.

Вот валидатор
import {EmailService} from './email.service';
import {catchError, map} from 'rxjs/operators';
import {AbstractControl, AsyncValidator, ValidationErrors} from '@angular/forms';
import {Observable} from 'rxjs';
import {Injectable} from '@angular/core';

@Injectable({ providedIn: 'root' })
export class EmailExistsValidator implements AsyncValidator {
  constructor(private emailService: EmailService) {}

  validate(
    ctrl: AbstractControl
  ): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
    return this.emailService.Is_email_exists(ctrl.value).pipe(
      map(isTaken => (isTaken ? { uniqueAlterEgo: true } : null)),
      catchError(() => null)
    );
  }
}


По примеру, на который я сслылался ранее, валидатор нужно заинжектировать - я меняю только одну строку в файле registration-page.component.ts,
constructor() { }
на
constructor(private emailExistsValidator: EmailExistsValidator) { }

и после этого я не могу зайти localhost:4200/registration - меня редирктит на главную страницу. Ошибок в терминале никаких, вроде-бы, нет.
В чём тут может быть дело?
Я старался свой вопрос не захламлять исходниками, но если для решения проблемы не хватает инфы - пожалуйста, говорите и я добавлю к вопросу дополнительные исходные коды
  • Вопрос задан
  • 132 просмотра
Решения вопроса 1
Xuxicheta
@Xuxicheta Куратор тега Angular
инженер
Не знаю почему вас редиректит, видимо ошибка где-то перехватывается. ngOnInit в компоненте должен бросать эксепшн у вас.

На первый взгляд вижу:
1. асинк валидаторы передаются в третьем параметре FormControl, а у вас во втором, вместе с простыми валидаторами.

Далее, делать валидатор через сервис, реализующий AsyncValidator смысла не вижу, в примерах его используют для создания директив. В вашем примере в директиву провайдится валидатор с помощью токена NG_ASYNC_VALIDATORS.
Можно наверно заюзать AsyncValidator и для компонента (типа реализующего ControlValueAccessor), но нужно будет тоже провайдить указывая токен (но это не точно). Обычно в этом просто нет нужды.

Для простой асинх валидации можно использовать функцию-фабрику валидатора, который берет зависимости от компонента.
Вот так https://ng-run.com/edit/DDaBjbxR39I7DIImTg0n

Да, и еще. Ваш валидатор будет делать запросы на каждый вводимый в форму символ. Чтобы этого избежать, нужно указать updateOn.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы