このような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"
}
]
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用に更新
@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();
}