An excerpt from an Angular class:
optionalString = new BehaviorSubject<string | undefined>(undefined);
// used to show that there may be multiple conditions involved
alwaysTrueFlag = new BehaviorSubject<boolean>(true);
ngOnInit(): void {
combineLatest([
this.optionalString.pipe(skip(1)),
this.alwaysTrueFlag
]).pipe(tap(([str, flag]) => {
// I hope `str` is a valid number, but it's getting
// "forwarded" to `subscribe` anyway...
})).subscribe(result => explodeIfNotNumber(result));
}
onKeyPress() {
this.optionalString.next(prompt('please enter a number'));
}
Since I can't control what happens in subscribe
, I'd like to avoid its getting triggered – unless the value obtained from the observable is valid (in this case a valid number).
I could control the source, i.e. this onKeyPress
here, and check if the entered string may safely be converted to a number, but I can't guarantee that every user of optionalString
is going to follow this, so I want to build validation into the observable itself.
If I'm going about this the wrong way, please tell me the conventional way of doing it. I haven't been able to find anything useful by googling. Thanks.
You could filter out non-numeric values.
import { filter, map, skip, tap } from 'rxjs/operators';
..
...
ngOnInit(): void {
combineLatest([
this.optionalString.pipe(skip(1)),
this.alwaysTrueFlag
]).pipe(
map(([str, flag]) => ({str, flag})), // Added to simplify the code in the next steps
filter(({str}) => !isNaN(Number(str))), // Filter the values and emit only valid numbers
tap(({str, flag}) => {
// Only run for valid numbers & numeric values
})
).subscribe(({str}) => explodeIfNotNumber(str));
}
Since filter is added, subscribe
would only be triggered if the input is numeric