Загрузка данных c из хранилища после загрузки данных из API - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть этот RXJS эффект в моем проекте, когда по действию я загружаю организацию с сервера, а затем пытаюсь выбрать закладку из магазина 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 и увидеть данные , за исключением последнего, который никогда не попадет , поэтому я подозреваю, что у меня могут быть проблемы с моим селектором закладок.

Мой селектор закладок выглядит следующим образом, и в данный момент в массиве нет закладок, поэтому эта функция возвращает 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;
  }
);

Мне это кажется немного грязным, и я Я ищу несколько советов о том, как я могу улучшить этот код, и в то же время sh эта ошибка!

1 Ответ

1 голос
/ 07 февраля 2020

Кажется, что последний forkJoin ничего не излучает (из определения)

Если внутренняя наблюдаемая не завершает, forkJoin никогда не выдаст значение!

следует что ваш селектор должен complete

Я предлагаю использовать take(1)/first на селекторе, чтобы завершить его (также, кроме того, попробуйте использовать startWith (но я думаю, что undefined должно быть в порядке)).

Кроме того, "действие" switchMap переводится в map - нет необходимости "выравнивать"

Должно работать так:

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})
),

Для общих настроек: немного упростить это (если возможно) - намного ofs, switchMaps, возможно, взгляните на разницу между zip/combineLatest/etc

...