从 API 加载数据后从商店加载特定数据

Loading specific data from the store after loading data from an API

我在我的项目中有这个 RXJS 效果,在这个操作中我从服务器加载一个组织,然后尝试 select 来自 NGRX 商店的书签基于organisation ID。在效果结束时,我使用数据发送我的成功操作。


selectOrganisation$ = createEffect(() => this.actions$.pipe(
    ofType(OrganisationsActionTypes.SelectOrganisation),
    withLatestFrom(
      this.store.pipe(select(AuthSelectors.selectCurrentUser)),
      this.store.pipe(select(ContextSelectors.getContext))
    ),
    switchMap(([action, user, context]) =>
      forkJoin([
        of(user),
        of(context),
        this.organisationService.getOrganisationById(context, action.id),
        this.moduleService.getAllSimpleModules(context)
      ])
    ),
    switchMap(([user, context, organisation, modules]) =>
      forkJoin([
        of(organisation),
        of(modules),
        this.store.pipe(select(BookmarkSelectors.selectBookmarkByOrganisation, {
          userId: user.id,
          context,
          organisationKey: organisation.key
        }))
      ])
    ),
    switchMap(([organisation, modules, bookmark]) => [
      onSelectOrganisation({organisation, modules, bookmark})
    ]),
    catchError(error => of(onSelectOrganisationError()))
  ));

问题是我的成功操作从未触发,我也没有得到任何类型的 error 抛出。 我可以在所有 switchMaps 中断点效果并查看数据 除了最后一个,它永远不会被击中 所以我怀疑我的书签可能有问题 select或.

我的书签select或者看起来像这样,此时数组中没有书签,所以这个函数returns undefined.

export const selectBookmarkByOrganisation = createSelector(
  selectAllBookmarks,
  (bookmarks: BookmarkDto[], props) => {
    const bookmark = _.chain(bookmarks)
      .filter(b =>
        b.userId === props.userId
        && b.serverContext === props.context
        && b.organisationKey === props.organisationKey)
      .first()
      .value();
    return bookmark;
  }
);

对我来说,这似乎有点混乱,我正在寻找一些关于如何改进此代码并同时消除此错误的指示!

似乎最后一个 forkJoin 没有发出任何东西(根据定义)

If an inner observable does not complete forkJoin will never emit a value!

您的选择器应该 complete

我建议在选择器上使用take(1)/first来完成它(另外,另外,尝试使用startWith(但我认为undefined应该可以)。

此外,"action's" switchMap 转移到 map - 不需要 "flatten"

应该像这样工作:

switchMap(([user, context, organisation, modules]) =>
  forkJoin([
    of(organisation),
    of(modules),
    this.store.pipe(
      select(BookmarkSelectors.selectBookmarkByOrganisation, {
        userId: user.id,
        context,
        organisationKey: organisation.key
      }),
      take(1),
    )
  ])
),
map(([organisation, modules, bookmark]) =>
  onSelectOrganisation({organisation, modules, bookmark})
),

对于一般调整:稍微简化一下(如果可能的话)- 尽量 ofsswitchMaps,也许看看 zip/combineLatest/etc

之间的区别