如何过滤可观察物?

时间:2018-11-27 22:16:41

标签: angular rxjs ng-bootstrap angular2-observables

我正在使用带有Firebase的ngbootstrap提前输入组件。

我试图找出如何根据返回的所有文档的名字来过滤可观察对象的结果。

遇到错误:[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 :(得分:1)

更改为

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

更新

如果getAllContacts返回observable,则将方法更改为下面的方法,然后从上面的旧答案中删除from()运算符。

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

答案 1 :(得分:0)

我在上面的代码中看到了许多问题。 Fan已经指出了从Promise到Observable的错误,但是当解决了这个问题后,下一个问题就出现了。

给我的第二个问题似乎是您可能在同一代码中混合了rxjs版本-您是否从其他位置复制并粘贴了它? res.filter本可以使用较旧的rxjs语法调用filter运算符,但是对于v6 +,该语法已更改,现在filter的调用方式有所不同。 slice甚至更老,回到rxjs v4(现在已由skip&take组合取代-请注意,在下面的代码中,我删除了skip,因为它将是skip(0),它什么都不做)

因此,如果filterslice是要作为结果Observable的运算符,则该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([]);
    }))
  ),
)

但是,我认为那真是一团糟的混乱代码。所有这些让我觉得它可以大大简化。


鉴于您在下面的评论中提到的内容,此处可能是上述代码的简化。摆脱返回a promise的异步函数,并在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([]))
    ))
);