Angular 2: How to use an observable filter

I have a service that calls the API as follows:

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); 

Now I want to implement a filter function for this call using rxjs/add/operator/filter , but I cannot get it to work correctly.

This is the approach I did:

 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); 

But no matter what I filter, the ngFor loop ngFor nothing while the filter is there. If I remove it, everything will work as expected.

Should I add a filter before or after map ?

Can I filter on a JSON response like this, or do I need to use a different syntax?

JSON example

Here is an example of what the JSON response looks like:

 data: [ { "Type": 5, "Description": "Testing", "ID": "001525" } ] 
+6
source share
2 answers

Whether filter() should be before or after map() depends on what you want to do.

I assume that in your case map() should go before filter() because you want to decode the data from JSON first and then filter it. What you have now will not give anything if the condition in filter() converted to false because you use in for the entire response . Maybe this is what you are going to ...

I don't know what your answer structure is, but I would go with something like this, which makes more sense:

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

Edit:

I would use concatMap() with from() to convert the array to an observable stream:

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

Watch a live demo: http://plnkr.co/edit/nu7jL7YsExFJMGpL3YuS?p=preview

January 2019: updated for RxJS 6

+12
source

Here's another example based on @martin's answer:

  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(); } 
+2
source

Source: https://habr.com/ru/post/1258381/


All Articles