Angular 2:如何使用Observable过滤器

时间:2016-10-18 05:53:43

标签: angular rxjs observable

我有一个像这样调用API的服务:

return this._http
        .post(appSettings.apiUrl + 'SomeController/SomeAction', params, {withCredentials: true, headers: this.headers})
        .timeoutWith(appSettings.maxTimeHttpCalls, Observable.defer(() => Observable.throw(this._feedbackService.timeout())))
        .map((response: Response) => response.json().data);

现在我想使用rxjs/add/operator/filter在该调用上实现过滤功能,但我无法使其正常工作。

这是我采取的方法:

return this._http
        .post(appSettings.apiUrl + 'SomeController/SomeAction', params, {withCredentials: true, headers: this.headers})
        .timeoutWith(appSettings.maxTimeHttpCalls, Observable.defer(() => Observable.throw(this._feedbackService.timeout())))
        .filter(response => response.json().data.Type === 5)
        .map((response: Response) => response.json().data);

但无论我过滤什么,只要过滤器在那里,ngFor循环就不会产生任何效果。如果我删除它,一切都按预期工作。

我应该在map之前或之后添加过滤器吗?

我可以像这样过滤响应JSON,还是需要使用其他语法?

示例JSON

以下是JSON响应的示例:

data: [
    {
        "Type": 5,
        "Description": "Testing",
        "ID": "001525"
    }
]

2 个答案:

答案 0 :(得分:14)

filter()map()之前或之后是否应该取决于您想要做什么。

我想在你的情况map()应该在filter()之前,因为你想首先从JSON解码数据然后过滤它。如果filter()中的条件解析为false,您现在的方式将无法返回任何内容,因为您在整个response中使用了。也许这就是你要去的......

我不知道你的回应结构是什么,但我会选择更合理的东西:

map((response: Response) => response.json().data),
filter(data => data.Type === 5),

编辑:

我将concatMap()from()一起使用,将数组转换为Observable流:

pipe(
  map(content => response.json().data),
  concatMap(arr => Observable.from(arr)),
  filter(item => item.Type === 5),
).subscribe(val => console.log(val));

查看现场演示:http://plnkr.co/edit/nu7jL7YsExFJMGpL3YuS?p=preview

2019年1月:更新了RxJS 6

答案 1 :(得分:2)

这是另一个基于@ martin答案的样本:

  public searchMediData(searchtearm: string) : Observable<MediData[]> 
  {  

    return this.http
               .get(this.url)
               .map(response => { 
                  let data = response.json();
                  let medidata = data as MediData[];
                  return medidata;
                })
                .concatMap(array => Observable.from(array))
                .filter(medi => {
                        let searchTearmUpperCase = searchtearm.toUpperCase();
                        let mediNameUpperCase = medi.Name.toUpperCase();                       
                        return mediNameUpperCase.includes(searchTearmUpperCase);
                 })
                .toArray();
  }