Побочные эффекты, когда значение фильтруется с помощью оператора filter () - PullRequest
0 голосов
/ 05 мая 2019

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

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

private setUserSearchObservable() {
    this.userSearch = userSearch$.pipe(
      tap(() => this.loading = true),
      debounceTime(500),
      this.filterValuesWithErrorMessages(),
      ......
    );
}

private filterValuesWithErrorMessages() {
    return pipe(
      tap((val: string) => { if (this.usernamesMatch(val)) { this.errorMessage = 'You will be added to the frame automatically'; this.loading = false; }}),
      tap((val: string) => { if (this.usernameInArray(val)) { this.errorMessage = 'User is already added'; this.loading = false; }}),
      tap((val: string) => { if (val.length < 2) { this.errorMessage = ''; this.loading = false; }}),
      filter((val: string) => (val.length >= 2 && !this.usernamesMatch(val) && !this.usernameInArray(val))),
    );
}

Как видите, я явно проверяю те же условия, используя tap (), прямо перед их использованием в filter (). Есть ли оператор / другой шаблон, который позволит мне добиться этого более кратким способом?

1 Ответ

2 голосов
/ 05 мая 2019

Рефакторинг вашего кода немного, нет конкретного оператора для проверки ошибок, вы можете использовать switchMap и внутреннюю наблюдаемость, например, of, never, чтобы контролировать, должен ли результат проходить.

private setUserSearchObservable() {
    this.userSearch = userSearch$.pipe(
      tap(() => this.loading = true),
      debounceTime(500),
      map((value) => this.filterValuesWithErrorMessages(value)),
      swtichMap(msg => {
        if (msg !== false) {
          this.errorMessage = result
          this.loading = false
          return never()
        }
        return of(true)
      })
    );
  }

  private filterValuesWithErrorMessages(val) {
    if (this.usernamesMatch(val)) return 'You will be added to the frame automatically'
    if (this.usernameInArray(val)) return 'User is already added'
    if (val.length < 2) return ''
    return false
  }
...