在调度一个动作和 NgRx 效果之前执行多个 API 调用
Posted
技术标签:
【中文标题】在调度一个动作和 NgRx 效果之前执行多个 API 调用【英文标题】:Performing multiple API calls before dispatching an Action an NgRx Effect 【发布时间】:2022-01-06 10:36:28 【问题描述】:我正在使用 NgRx @Effect
,为了达到某些效果,我需要执行 2 个 API 调用:第一个的结果用于第二个,我想用第二个 API 调用调度 Action
像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
所以我认为我的操作员编排不正确!
【问题讨论】:
【参考方案1】:也许你需要一个新函数,它会调用getContext()
,但会返回你需要的东西。类似的东西:
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()
以返回给定的操作。
【讨论】:
很抱歉,语法上两者都不被接受:( 错误是什么? 我的 IDE 不接受语法.. 这是截图:ibb.co/cgb5MSd 看不到,如果是因为解构,我已经更新了我的帖子。 是的,这是因为破坏。但即使是第二个解决方案也不起作用......这是一个截图:prnt.sc/20zdqjy【参考方案2】:只需在管道内部执行此操作:
@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)))
)
)
【讨论】:
是的,它是这样工作的!谢谢 !我找到了使用contactMap的另一种方法,我会发布它【参考方案3】:这是我使用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 效果之前执行多个 API 调用的主要内容,如果未能解决你的问题,请参考以下文章