Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rxjs conditional nesting observables

I have the following code which is working as intended:

const sourceObservable = ... // irrelevant
sourceObservable.subscribe(x => {
    doAnyway(x);
    if (x.Id) {             
        doSometing(x);
    } else {
        // id Not set, get default Id
        this.idService.getDefault().subscribe(id => {
            x.Id = id;                  
            doSometing(x);
        });
    }
});

According to this article nested subscribes are to avoid. Thats why i tried to refactor the above code, using pipes. I tried to realize the if-else operation with this Method, where filtering is used to create an observable branch for each option. And in the end they should be merged to subscribe.

const obsShared = sourceObservable.pipe(
tap(x => {
    doAnyway(x);
}),
share());

const obsIdNotSet = obsShared.pipe(
    filter(x => !x.kennzahlId),
    merge(x => idService.getDefault().subscribe(id => {
            x.Id = id;
        // doSomething(x) will nomore be executed here
        })));

// even though the true-part is empty I seem to need this to mergeing both options
const obsIdSet = obsShared.pipe( 
    filter(x => !!x.Id),
    tap(() => {
        // doSomething(x) will nomore be executed here
    }));

obsIdSet.pipe(merge(obsIdNotSet)).subscribe(x => {  
    // in case obsIdNotSet this will run with x.Id not set because x.Id will be set later
    doSometing(x);
});

This code does compile and run without errors, only does it execute doSomething(x) before calling idService.getDefault()..... and though it will be called without x.Id being set.

What am i doing wrong?

like image 949
LuckyLikey Avatar asked Sep 07 '25 03:09

LuckyLikey


1 Answers

the following is the cleanest way to handle that (according to me) :

source.pipe(
  tap(val => doAnyway(val)),
  switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
  this.id = id;
  doSomething(id);
});

You can see how short and clear this is, and it does the exact same thing your first code was doing.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!