how to filter an Observable array?
Solution 1
You should be able to use the map
and the filter
operators for this, combined with Array.prototype.filter
. If I've understood your data correctly it should be something like this:
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
userEvents: Observable<any[]>;
constructor(public auth: AuthService, private upSvc: FilesServiceService) {
this.userEvents = this.upSvc.getUserEvents(this.auth.currentUserId)
.map(items => items.filter(item => item.attending))
.filter(items => items && items.length > 0);
}
First we filter the array down to only items where attending
is true.
Then we filter out any empty or null arrays.
Updated for RXJS 6:
import { pipe } from 'rxjs';
import { map, filter } from 'rxjs/operators';
userEvents: Observable<any[]>;
constructor(public auth: AuthService, private upSvc: FilesServiceService) {
this.userEvents = this.upSvc.getUserEvents(this.auth.currentUserId)
.pipe(
map(items => items.filter(item => item.attending)),
filter(items => items && items.length > 0)
);
}
Solution 2
You cannot use the rxjs filter method for this, but rather the filter method on the array object that you receive from the observable.
So if you have an Observable<any[]>
you would filter it like this:
import 'rxjs/add/operator/map';
this.userEvents.map( arr =>
arr.filter( r => r.attending === true )
)
.subscribe( results => console.log('Filtered results:', results))
From rxjs 5.5 you should use .pipe
instead of .map
directly on the Observable:
import { map } from 'rxjs/operators';
this.userEvents.pipe(
map(arr =>
arr.filter( r => r.attending === true )
)
)
.subscribe( results => console.log('Filtered results:', results))
Fernando Nicolalde
Updated on June 04, 2022Comments
-
Fernando Nicolalde about 2 years
My method returns an Observable array from Firebase. I have decided to filter the data in the client rather than in the server. My problem is that I want to get only the data if the attribute "attending = true". Any help or other approach is highly appreciated. Thank you very much.
The method below get the data from the firebase real-time database
userEvents: Observable<any[]>; getUserEvents(uid: string) { this.userEvents = this.db.list(this.basePatheventsSaved, ref=> ref.orderByChild('uid').equalTo(uid)).snapshotChanges().map((actions) => { return actions.map((a) => { const data = a.payload.val(); const $key = a.payload.key; return { $key, ...data }; }); }); return this.userEvents; }
The code below is used to fecth the data to be used in the templaTe:
userEvents: Observable<any[]>; constructor(public auth: AuthService, private upSvc: FilesServiceService) { this.userEvents = this.upSvc.getUserEvents(this.auth.currentUserId); }
-
Fernando Nicolalde over 6 yearsWhen applying the first option at runtime I get the error map is undefined, and the in the second one "pipe" has not exported member. The problem is solved though. Thank you very much for your help
-
Peter Salomonsen over 6 yearsSorry should have imported map on both options and not import pipe on the second. Corrected now.
-
TomerBu almost 5 yearsConsider changing the following sentence: "You cannot use the rxjs filter method for this" IMO You should also use the rxjs filter method to filter out any empty or null arrays.