Reputation: 1036
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
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
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 —
They map some value to an observable (you are the one in charge of returning an observable value from them, they just map it)
They flatten the observable you return ( they just subscribe to it)
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
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