'How to do something conditionally with Observables before subscribe?
I'm trying to implement a solution that execute the following steps:
- Check if a condition is valid with a
filter
. - Check if
Ctrl
is pressed and execute some function if it is. - finally, execute another function.
I was able to make it work with that code:
const click = Observable.fromEvent(element, 'click');
click.filter(() => condition)
.do((event: MouseEvent) => {
if (!event.ctrlKey) {
// maybe do something...
}
}).subscribe(() => {
// aways do something else at end
});
I want to know if there is a more elegant solution that removes the if condition inside of do
method?
Solution 1:[1]
Not sure I understand the question, but here's a similar way of doing that and trying to keep the code as clean as possible :
const click$ = Observable.fromEvent(document, 'click');
// I don't know what's in your condition so I just return true
const condition = () => true;
const fnCtrlIsPressed = () => 'Ctrl is pressed';
const fnCtrlIsNotPressed = () => 'Ctrl is not pressed';
click$
.map(event => event.ctrlKey)
.map(isCtrlPressed => isCtrlPressed ?
fnCtrlIsPressed():
fnCtrlIsNotPressed())
.do(console.log)
.subscribe();
The output will be something like that :
Here's a working Plunkr : https://plnkr.co/edit/VwuXkk0QnVGC4hPCvtOo?p=preview
Solution 2:[2]
One option is to flatMap with a stream that triggers the appropriate action in case Ctrl is pressed, it is not much different from your approach.
const condition = () => true;
const clickStreamWithCtrlAction = Observable.fromEvent(element, "click")
.flatMap(event => event.ctrlKey
? Observable.of(event).do(clickWithCtrl => console.log("With ctrl clause"))
: Observable.of(event)
)
clickStreamWithCtrlAction
.filter(condition)
.subscribe(event => console.log(`Finally clause, ctrlKey: ${event.ctrlKey}`));
Solution 3:[3]
why you don't use pipe method. that is something like this:
import { Observable, tap, filter } from 'rxjs';
const click = Observable.fromEvent(element, 'click')
.pipe(filter((valueEmitted) => {
//your filter comes here. if everything ok return true;
}), tap((valueEmitted) => {
//do something before subscribe
}));
and after that you can subscribe to click observable.
more details about tap: https://www.learnrxjs.io/learn-rxjs/operators/utility/do
more details about filter: https://www.learnrxjs.io/learn-rxjs/operators/filtering/filter
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | maxime1992 |
Solution 2 | Tal |
Solution 3 | Amir Hesari |