Asyn c валидатор типа Observable никогда не заканчивается - PullRequest
0 голосов
/ 17 января 2020

Я делаю веб-приложение в Angular 8 и Firebase Firestore. У меня есть форма с одним входом для ввода идентификационного номера (в виде строки). Я хочу проверить, есть ли пользователь с таким идентификатором.

Я попытался реализовать asyn c валидатор. Он проверяет, существует ли идентификатор, если нет, возвращает ошибку для отображения сообщения в шаблоне.

constructor(
    private clientService: ClientService,
    private fb: FormBuilder,
  ) {
    this.clientForm = fb.group({
      identificationNumber: ['', [
        Validators.required,
        Validators.minLength(11)
      ], CustomValidator.validateUser(this.clientService)]
    });
  }

Валидатор asyn c:

static validateUser(clientService: ClientService): AsyncValidatorFn {
    return (control: AbstractControl):
      Promise<ValidationErrors | null> |
      Observable<ValidationErrors | null> => {
      if (control.value.length !== 11) {
        return of(null);
      } else {
        return control.valueChanges.pipe(
          debounceTime(1000),
          switchMap(_ =>
            clientService.getClientByIdentificationNumber(control.value)
              .pipe(
                map(client => return client ? null : {notfound: true}),
                catchError(err => return of(null))
              )
          ),
          first(),
        );
      }
    };
  }

Метод из службы, чтобы получить пользователя:

getClientByIdentificationNumber(identificationNumber: string): Observable<Client> {
    return this.afs
      .collection(
        'clients',
        ref => ref.where('identificationNumber', '==', identificationNumber)
          .limit(1) // Just get one
      )
      .snapshotChanges().pipe(
        // flatMap() will return a single Client
        flatMap(actions => actions.map(a => {
          const data = a.payload.doc.data() as Client;
          const id = a.payload.doc.id;

          console.log('getClientByIdentificationNumber'); // Called several times

          return {id, ...data};
        }))
      );
  }

Метод getClientByIdentificationNumber из службы вызывается снова и снова, он никогда не заканчивается.

Моя цель - проверить, есть ли клиент с таким идентификатором и возвращает ошибку, правильно обрабатывая Observables для предотвращения утечек и оставляя открытые подписки по ошибке.

...