Reputation: 354
Is there a way to convert a set of nested async promises into an @Effect?
I have a transaction that uses multiple async http calls where I have to wait for a result before going to the next step and any error aborts the transaction and sends an error message to the user.
I'm fairly new to rxjs and it seems like I can kind of get the same action as "Promise...then" with exhaustMap, but I'm not exactly sure how to do it and capture the errors along the way.
My goal is to move the entire transaction (currently in a service) to an ngrx @Effect.
Upvotes: 0
Views: 484
Reputation: 5911
First of all I would do multiple effects with each effect dispatching a new action. It's just more comprehensible and you get a log in the reduce-devtools.
@Effect()
public makeFirstRequest = this.actions.pipe(
ofType<InitialAction>(ActionTypes.InitialAction),
switchMap(action => this.myService.firstRequest(action.param)),
map(response => new FollowUpAction(response))
);
@Effect()
public makeSecondRequest = this.actions.pipe(
ofType<FollowUpAction>(ActionTypes.FollowUpAction),
switchMap(action => this.myService.secondRequest(action.param)),
map(response => new NextAction(response))
);
// and so on...
This way it first executes the InitialAction
and makes the request and as soon as the request is completed it executes the FollowUpAction
. You can pass the response as parameter of the next action. Remember that you don't have to pass the response to the next action. You can do whatever you want with the response and dispatch a new action with whatever parameters (or no parameters) you like.
And I am not sure if this is included in your question but you need observables and not promieses. If you do use promises you can simply use from(myPromise)
provided by rxjs
to map it into an observable.
Upvotes: 0
Reputation: 628
Let us suppose a
and b
are observables then you can wait for all the observables got resilved using forkJoin method.
Rx.Observable.forkJoin([a,b]).subscribe(result=> {
var resultA = result[0];
var resultB = result[1];
});
Upvotes: 1
Reputation: 1436
I am not sure if I really understand your problem but it seems like you could just use Promise.all()
to make a collection of promises into a single promise which could then be used in your @Effects.
See Promise.all() definition
Upvotes: 0