I want to resolve an observable but I don't want the return value to replace the previous value in the pipe. Is there any asynchronous tap()
? I need an operator like a switchMap
but I want to ignore the return.
of(1).pipe(switchMap(() => of(2))).subscribe(console.log); // expected: 1
I could create a custom operator but sure there's something built-in in rxjs.
SwitchMap switches to the most recent observable The SwitchMap operator returns an observable using the interval method. The interval method creates an infinite observable, which emits a sequence of integers spaced by a given time interval.
switchMap has only one active subscription at a time from which the values are passed down to an observer. Once the higher-order observable emits a new value, switchMap executes the function to get a new inner observable stream and switches the streams.
RxJS switchMap() operator is a transformation operator that applies a project function on each source value of an Observable, which is later merged in the output Observable, and the value given is the most recent projected Observable.
I ended up with this custom operator. It is like tap but resolves observables (and should be updated to also support promises).
export function switchTap<T, R>(next: (x: T) => Observable<R>): MonoTypeOperatorFunction<T>;
export function switchTap<R>(observable: Observable<R>): MonoTypeOperatorFunction<R>;
export function switchTap<T, R>(
arg: Observable<T> | ((x: T) => Observable<R>)
): MonoTypeOperatorFunction<T> {
const next: (x: any) => Observable<T | R> =
typeof arg === 'function' ? arg : (x: any): Observable<T> => arg;
return switchMap<T, T>(value => next(value).pipe(ignoreElements(), concat(of(value))));
}
Usage:
of(1).pipe(switchTap(of(2))).subscribe(console.log) // 1
or with a function:
of(1)
.pipe(
switchTap(value => {
console.log(value); // value: 1
return of(value + 1);
})
)
.subscribe(console.log); // 1
If you just want to simply ignore the values of the subscribe, then just don't pass in any arguments in the subscribe
callback:
of(1).pipe(switchMap(() => of(2))).subscribe(()=>{
console.log('no arguments')
});
If you however want to retain the values of the first observable, things can get tricky. One way is to use Subject
to retain the value:
//create a BehaviorSubject
var cache = new BehaviorSubject<any>(0);
of(1).pipe(switchMap((first) => {
cache.next(first);
return of(2);
})).subscribe(() => {
console.log(cache.value) //gives 1
});
Or you can use .map()
to alter the values. This is kind of hacky and the code is harder to maintain:
of(1).pipe(switchMap((first) => {
return of(2).map(() => first);
})).subscribe((second) => {
console.log(second) //gives 1 because the values was mapped
});
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