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.
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
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));
}))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With