【问题标题】:Angular 2: How to use Observable filterAngular 2:如何使用 Observable 过滤器
【发布时间】:2016-10-18 05:53:42
【问题描述】:

我有一个像这样调用 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"
    }
]

【问题讨论】:

  • 最可能的解释是json的data字段的Type字段不等于5。什么是json?

标签: angular rxjs observable


【解决方案1】:

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 更新

【讨论】:

  • 我添加了一些示例 JSON。我最后用过滤器尝试了你的方式,并过滤了 data.Type === 5data.ID === '001525' 但都失败了。
  • @GlennUtter 这就是我的想法。 data 是一个对象数组,但 map((response: Response) => response.json().data) 将其作为一个大数组返回,然后将其传递给过滤器。所以你想迭代结果并只返回 data.Type === 5? 的对象?
  • @GlennUtter 比它复杂一点。通过演示查看我的更新答案。
  • 谢谢先生。我已经修改了我的代码,但是在 filter 语句中这样做时我得到了Property 'Type' does not exist on type '{}'
  • @GlennUtter 好的,这是编译时的 TypeScript 错误吗?您可以改用item['Type'] 或在.filter(item:Whatevertypeitis => ... 中定义正确的类型
【解决方案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();
  }

【讨论】:

  • 你可以写 .map(response => response.json().data as MediData[])。
猜你喜欢
  • 1970-01-01
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2021-07-23
  • 2021-08-31
  • 1970-01-01
相关资源
最近更新 更多