Запустить действие перед отправкой запроса в эпике, наблюдаемой с редукцией

Я хочу запустить действие перед отправкой запроса на сервер. Вот мой код:

public fetchUserPrjects(action$: Observable<IProjectAction>, store: Store<IAppState>) {
    return action$.pipe(
      ofType(ProjectActionType.FETCH_USER_PROJECTS),
      mergeMap((action) => {
        store.dispatch(this._commonAction.showLoading()); // <== call action before request
         return this._projectService.getProjectList(action.payload)
          .map((result) => {
               return {
              project: result
            };
          });
      }),
      flatMap(data => [
        this._projectAction.addUserProjects(data),
        this._commonAction.hideLoading()
      ])
    ).catch((error) => {
      return Observable.of(this._commonAction.showError(error));
    })
    .concat(Observable.of(this._commonAction.hideLoading()));
  }

Я перепробовал много способов и остановился на этом. Однако этот способ иногда работает, а иногда нет. Иногда зависает весь процесс. Как я могу запустить действие перед отправкой запроса на сервер?


person Amir Movahedi    schedule 26.03.2018    source источник


Ответы (2)


Вы можете удалить отправку showLoading из эпика fetchUserProjects, а затем просто создать второй эпик с помощью:

return action$.pipe(
      ofType(ProjectActionType.FETCH_USER_PROJECTS),
      map(() => this._commonAction.showLoading())
    );

Порядок выполнения на самом деле не имеет значения, потому что запрос this._projectService.getProjectList является асинхронным и, следовательно, обязательно разрешится впоследствии.

person Kim Kern    schedule 26.03.2018
comment
Спасибо! Однако проблема в том, что я хочу передать action для this._projectService.getProjectList(action.payload). При этом, если я сначала выполню map(() => this._commonAction.showLoading()), я не смогу передать действие из функции ofType() в getProjectList(). - person Amir Movahedi; 26.03.2018
comment
Я думаю, что произошло недоразумение, поэтому я отредактировал свой ответ, чтобы сделать его более понятным. Ничто не мешает вам иметь несколько эпиков, «слушающих» один и тот же тип действия. - person Kim Kern; 27.03.2018

Как насчет этого:

 return action$.pipe(
      ofType(ProjectActionType.FETCH_USER_PROJECTS),
      flatMap(action => Observable.concat(
        this._projectService.getProjectList(action.payload)
            .map(this._projectAction.addUserProjects({ project: result}))
            .startWith(this._commonAction.showLoading())
            .catch(error => this._commonAction.showError(error)),
        Observable.of(this._commonAction.hideLoading())
      )))
person miles_christian    schedule 26.03.2018