Как отфильтровать наблюдаемое? - PullRequest
0 голосов
/ 28 ноября 2018

Я использую компонент typeghead ngbootstrap с firebase.

Я пытаюсь выяснить, как отфильтровать результаты наблюдаемой на основе имени всех возвращенных документов.

При возникновении ошибки: [ts] Property 'pipe' does not exist on type 'Promise<any>'. [2339]

async  getAllContacts(term){
    let res = this.contactService.getAllContacts();

    return await res.filter(v => v.firstname.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)
  }
  search = (text$: Observable<string>) =>
  text$.pipe(
    debounceTime(300),
    distinctUntilChanged(),
    switchMap(term =>
      this.getAllContacts(term).pipe(
        catchError(() => {
          return of([]);
        }))
    ),
  )

Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

В коде выше я вижу ряд проблем.Фан уже указал на ошибку при переходе от Promise к Observable, но когда эта проблема была решена, следующая проблема возникла.

Эта вторая проблема для меня выглядит так, как будто вы смешиваете версии rxjs водин и тот же код - вы копировали и вставляли его из разных мест?res.filter вызвал бы оператор filter в более старом синтаксисе rxjs, но с v6 + этот синтаксис изменился, и теперь фильтр вызывается по-другому.slice еще старше, вернемся к rxjs v4 (теперь заменен комбо skip & take - примечание в приведенном ниже коде, я удалил skip, так как это будет skip (0), который ничего не делает)

, так что еслиfilter и slice должны быть операторами в результирующей Наблюдаемой, тогда версия rxjs6 будет выглядеть совсем иначе.

Если все, что происходит, вы можете изменить свой код на:

async getAllContacts(term) {
  let res = this.contactService.getAllContacts();

  return await res.pipe(filter(v => v.firstname.toLowerCase().indexOf(term.toLowerCase()) > -1),take(10))
}
search = (text$: Observable<string>) =>
text$.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap(term =>
    from(this.getAllContacts(term)).pipe(
      catchError(() => {
        return of([]);
    }))
  ),
)

Однако, я думаю, это настоящий беспорядок запутанного и запутанного кода.Все это заставляет меня думать, что это может быть значительно упрощено.


Учитывая то, что вы упомянули в комментариях ниже, вот возможное упрощение приведенного выше кода.Избавьтесь от асинхронной функции, которая возвращает обещание, и сделайте все это в search, примерно так:

search = (text$: Observable<string>) => text$.pipe(
    debounceTime(300),
    distinctUntilChanged(),
    switchMap(term => this.contactService.getAllContacts().pipe(
        filter(v => v.firstname.toLowerCase().indexOf(term.toLowerCase()) > -1),
        take(10),
        catchError(() => of([]))
    ))
);
0 голосов
/ 28 ноября 2018

Измените на

   switchMap(term =>
      from(this.getAllContacts(term)).pipe(
        catchError(() => {
          return of([]);
        }))
    ),

Обновите

Если getAllContacts верните наблюдаемый, измените метод на ниже и просто удалите оператор from () из старого вышеответ.

getAllContacts(term){
    return this.contactService.getAllContacts().pipe(map(res=>
    res.filter(v =>v.firstname.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)
))
}
...