I'm using NgRx @Effect
and for some effect I need to perform 2 API calls: the result of the first one is used in the second one and the I want to dispatch an Action
with the 2nd API call as payload
this way :
@Effect()
FetchDetails() {
return this.actions.pipe(
ofType(actions.SOME_ACTION),
switchMap((action: SomeAction) => this.myService.getContext()),
switchMap((ctx: Context) => this.myService.fetchDetails(action.id, ctx.requesterType)
.pipe(
map((response: Details) => new SetDetails(response)),
catchError(err => {return of(new SetFetchDetailsError(err))})
)
)
}
Using a double switchMap
like this I can't access action.id
so I think my operators orchestration is not correct !
CodePudding user response:
Just do this in pipe inside:
@Effect()
FetchDetails() {
return this.actions.pipe(
ofType(actions.SOME_ACTION),
switchMap((action: SomeAction) => this.myService.getContext().pipe(
switchMap((ctx: Context) => this.myService.fetchDetails(action.id, ctx.requesterType)
))
.pipe(
map((response: Details) => new SetDetails(response)),
catchError(err => {return of(new SetFetchDetailsError(err))})
)
)
}
CodePudding user response:
Maybe you need a new function, which will call getContext()
, but will return what you need. Something like :
getContextAction(action: SomeAction): Observable<any> {
return this.getContext().pipe(
map(ctx => { action, ctx });
}
Then
@Effect()
FetchDetails() {
return this.actions.pipe(
// ...
switchMap((action: SomeAction) => this.myService.getContextAction(action)),
switchMap((value) => this.myService.fetchDetails(value.action.id, value.ctx.requesterType)
// ...
}
You can also edit you current function getContext()
in order to return the given action.
CodePudding user response:
Here is the solution that I found using concatMap
operator :
@Effect()
FetchApiDetails() {
return this.actions.pipe(
ofType(apis.FETCH_SELECTED_API_DETAILS),
concatMap((action: FetchSelectedApiDetails) =>
this.contextInit.getContext()
.pipe(
switchMap((ctx: Context) => this.apisManagementService.fetchApiDetails(action.apiId, ctx.requesterType)
.pipe(
map((response: ApiDetails) => new SetApiDetails(response)),
catchError(err => {
return of(new SetFetchApiDetailsError(err))
})
)
),
catchError(err => {
console.log('An error happened when fetching context ' err);
return of(err);
})
)
)
);
}