The docs for DefaultIfEmpty mention a couple of other languages that support a similar operator called SwitchIfEmpty
http://reactivex.io/documentation/operators/defaultifempty.html
Are there plans to bring SwitchIfEmpty to RxJS, or has it been omitted intentionally? It would be very handy.
I've found a solution that achieves a similar result when dealing with a single-item observable, but having that operator would make it much easier.
Observable.of('set value').concat(Observable.of('default value')).first(); // 'set value'
Observable.empty().concat(Observable.of('default value')).first(); // 'default value'
defaultIfEmpty is a thing already.
Is there something else you needed?
@benlesh It's not DefaultIfEmpty that I need, it's SwitchIfEmpty. Removing a pronoun in my original comment to make that more clear.
Here's a solution for multi-item streams:
const default_placeholder = {};
const defaultObservable = doSomethingByDefault();
Source.defaultIfEmpty(default_placeholder).mergeMap(value => {
if (value === default_placeholder) {
return defaultObservable;
} else {
return Observable.of(value);
}
});
I see what you're asking for now. Switch seems like the wrong word to me. concatIfEmpty? I dunno. I'll think about this one
@benlesh I agree concatIfEmpty would make sense, but consistency with the other implementations is desirable.
No news about that? I was really in need of something like that and I don't know how to actually handle the situation without it...
I have a Observable that can be empty, and another one that has some pipe calculation. If the 1st is empty I want to use the 2nd... any ideas?
@gabrielalan Have a look at https://github.com/cartant/rxjs-etc/blob/master/source/operators/defaultObservableIfEmpty.ts
Thanks @cartant
I thought I wanted defaultIfEmpty this for this situation:
obs$.pipe(defaultIfEmpty(throwError('Your source observable was empty')))
But this is even better:
obs$.pipe(throwIfEmpty(() => 'Your source observable was empty')))
This can be useful in combineLatest where an EMPTY input deadlocks. You'd put throwIfEmpty on every input if you wanted to prevent the deadlock. Similar to this.
So I feel like I don't really need defaultIfEmpty(obs: Observable<T>), but still curious why it is in some flavors of Rx but not RxJS.
@benlesh and @cartant I guess we can close this. Right?
One way to do it with existing operators would be:
import { EmptyError, Observable, throwError } from 'rxjs';
import { catchError, throwIfEmpty } from 'rxjs/operators';
export function solve(first: Observable<string>, second: Observable<string>): Observable<string> {
return first.pipe(
throwIfEmpty(),
catchError((err) => err instanceof EmptyError ? second : throwError(err))
);
}
Most helpful comment
@gabrielalan Have a look at https://github.com/cartant/rxjs-etc/blob/master/source/operators/defaultObservableIfEmpty.ts