Lakindu Akash
Lakindu Akash

Reputation: 1036

Avoiding nested subcribe() calls in RxJs 6

Sometimes I need a value from previous observable and run another function that depend on that value and so on. It make nested subcribe() calls and then code is very ugly and unmanageable. I have an example here:

getObservableData().subcribe(next=>
    let dialogRef=this.dialog.open(EvalListComponent, {data: next})
    dialogRef.afterClosed().subscribe(next=>{
        let k=dialogRef.componentInstance.getAnotherObservableData()
            .subcribe( next=> doSomthing(next))
}))

What kind of solution can have situation like that. I need some flatten structure. I know there is a pipe function and can be use it with rxjs operators. But how can be it accomplished?

Upvotes: 5

Views: 2542

Answers (3)

thenolin
thenolin

Reputation: 1064

I would suggest looking at MergeMap and/or SwitchMap. SwitchMap can be used in order to complete one async call, determine if it completed successfully, and then make another async call with that data.

return getObservableData()
.switchMap(next => {
    return let dialogRef = this.dialog.open(EvalListComponent, {data: next}
})
.catch(error => {
    return Observable.of(...)
}
.switchMap(x => {
        ...
})
.catch( ...and so on and so on...)

Upvotes: 0

gr4viton
gr4viton

Reputation: 1514

I recommend this article: learn flattening strategies.

TLDR: use map operators like: mergeMap, switchMap, concatMap, exhaustMap.

All of them mostly work in the same manner —

  1. They map some value to an observable (you are the one in charge of returning an observable value from them, they just map it)

  2. They flatten the observable you return ( they just subscribe to it)

  3. They decide about what to do before / after they flatten (“Flattening Strategy”)

Only thing you have to decide about is which strategy is useful for your example. By reading the article you can figure it out easily.

Upvotes: 7

Vivek Kumar
Vivek Kumar

Reputation: 5050

Generally, I prefer creating Subject at the time of performing the asynchronous operation and listening for changes.

for example:
```

private dialogActionSubject: Subject<string>;

public onAlertActionBtnClicked(data): void {
    this.dialogActionSubject.next(data);
}

const subs = this.dialogActionSubject
    .pipe(
        distinctUntilChanged()
    )
   .subscribe(action => {});

```

Upvotes: 0

Related Questions