Reputation: 2874
Is there an operator in RxJS that works like filter()
but accepts a predicate that allows returning an Observable? So when the Observable returned by the predicate emits an event filter()
decides whether event from the original source should be discarded or not.
Upvotes: 3
Views: 3217
Reputation: 145950
Another way is using two switchMap
operators:
const animals$ = from(['cat', 'dog', 'fish']).pipe(switchMap(animal => {
// call webservice to determine if the animal is a mammal or not
// this returns an observable boolean (i.e. a predicate)
// this could be any Observable<boolean> of course
const isMammal$: Observable<boolean> = webService.isMammal(animal);
// when we get the result back if it's true then return the
// original 'animal' string (by creating a new observable with of())
// if it isn't an animal then return EMPTY, which has the same effect as filtering it out
return isMammal$.pipe(switchMap(isMammal => isMammal ? of(animal) : EMPTY));
}))
Upvotes: 1
Reputation: 96889
If I understand you correctly I'd do it like the following:
const Observable = Rx.Observable;
const Subject = Rx.Subject;
let subject = new Subject();
source = Observable.from([1,2,3,4])
.flatMap(val => subject
.withLatestFrom(Observable.of(val), (_, val) => val)
.filter(val => val % 2 == 0)
);
source.subscribe(val => console.log(val));
subject.next(null);
setTimeout(() => {
subject.next(null);
}, 1000);
I wrapped each value with another Observable and withLatestFrom
operator that emits only when its source emits. In my case the source is subject
so I have full control over it. Then there's filter()
that can filter whatever you want.
Although, I wonder if there's any easier solution...
This prints only two values and after 1s another two because I called subject.next(null);
inside the setTimeout
callback:
2
4
2
4
See live demo: https://jsbin.com/gasumiz/10/edit?js,console
Upvotes: 1