Почему мой AsyncValidator всегда возвращает true? - PullRequest
1 голос
/ 20 апреля 2020

Почему это всегда возвращает ошибку?

export class UserExistsValidatorService implements AsyncValidator {

  constructor(private userService: UserService) { }

  validate(control: FormControl): Observable<ValidationErrors | null> {
    return this.userService.existsUser(control.value)
      .pipe(map(exists => (exists === false) ? null : {
         userExists: { valid: false }
       }),
       catchError(() => of(null)));
   }
}

Эта реализация проверки вызывает метод службы, который возвращает Observable<boolean>

existsUser(username: string): Observable<boolean> {
   return this.http.post<any>(`${environment.apiUrl}/existsUser`, { username })
      .pipe(map(response => response.userExists === '1'))
      .pipe(catchError(this.errorHandler));
}

Я проверил, что служба работает правильно подписавшись и зарегистрировавшись для быстрого теста:

this.userService.existsUser(this.registerGrp.controls.username.value)
    .subscribe(exists => { console.log(exists); });

это печатает true / false, как я ожидаю.

Однако, мой FormGroup.invalid всегда возвращает false. Кажется, что валидатор всегда срабатывает.

ngOnInit(): void {
    // Formularmodell bauen
    this.registerGrp = this.formBuilder.group({
      username: ['', this.userExistsValidator],
      password: [''],
      // Confirm-Feld müsste eigentlich nicht auf required geprüft werden
      // confirmPassword: [''],
      confirmPassword: [''],
      xboxName: [''],
      discordName: [''],
      accepted: [false]
    });
}

console.log(this.registerGrp.invalid); // always false

Есть идеи?

1 Ответ

2 голосов
/ 20 апреля 2020

Angular не разворачивает ваше наблюдаемое, оно просто оценивает весь Observable объект, который всегда правдив.

Причина, по которой это происходит, заключается в том, что вы не говорите Angular, что это asyn c валидатор. control подпись может принимать до 3 параметров: состояние, список валидаторов syn c, список валидаторов asyn c.

В вашем случае, если у вас нет syn c валидаторов, вы можете передать null в качестве второго параметра:

username: ['', null, this.userExistsValidator],
...