在分派 Action 和 NgRx Effect 之前执行多个 API 调用
Performing multiple API calls before dispatching an Action an NgRx Effect
我正在使用 NgRx @Effect
并且为了某些效果我需要执行 2 API 调用:第一个的结果用于第二个并且我想发送一个Action
第二个 API 调用为 payload
这样:
@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))})
)
)
}
像这样使用双 switchMap
我无法访问 action.id
所以我认为我的运算符编排不正确!
也许您需要一个新函数,它会调用 getContext()
,但会 return 您所需要的。像 :
getContextAction(action: SomeAction): Observable<any> {
return this.getContext().pipe(
map(ctx => { action, ctx });
}
然后
@Effect()
FetchDetails() {
return this.actions.pipe(
// ...
switchMap((action: SomeAction) => this.myService.getContextAction(action)),
switchMap((value) => this.myService.fetchDetails(value.action.id, value.ctx.requesterType)
// ...
}
您还可以编辑当前函数 getContext()
以 return 给定的操作。
只需在管道内执行此操作:
@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))})
)
)
}
这是我使用 concatMap
运算符找到的解决方案:
@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);
})
)
)
);
}
我正在使用 NgRx @Effect
并且为了某些效果我需要执行 2 API 调用:第一个的结果用于第二个并且我想发送一个Action
第二个 API 调用为 payload
这样:
@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))})
)
)
}
像这样使用双 switchMap
我无法访问 action.id
所以我认为我的运算符编排不正确!
也许您需要一个新函数,它会调用 getContext()
,但会 return 您所需要的。像 :
getContextAction(action: SomeAction): Observable<any> {
return this.getContext().pipe(
map(ctx => { action, ctx });
}
然后
@Effect()
FetchDetails() {
return this.actions.pipe(
// ...
switchMap((action: SomeAction) => this.myService.getContextAction(action)),
switchMap((value) => this.myService.fetchDetails(value.action.id, value.ctx.requesterType)
// ...
}
您还可以编辑当前函数 getContext()
以 return 给定的操作。
只需在管道内执行此操作:
@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))})
)
)
}
这是我使用 concatMap
运算符找到的解决方案:
@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);
})
)
)
);
}