ngrx-确保所有http调用均已完成并存储在商店中

时间:2019-03-19 17:04:28

标签: angular store ngrx

我想要的内容的简短摘要

  • 调用api 1
  • 调用api 2
  • 等待直到这些数据保存在store
  • 通过effect级别获取这些数据

说明

我想做的就是简单地等待一些动作正确完成并存储在商店中。然后运行下一个。

例如,

@Effect()
  getData1$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.getData1Action),
    switchMap(action => {  // Simply call an api and save data in the store by calling GetData1Success.
      this.httpClient.get(...)
      .pipe(
        map((result) => new GetData1Success(result))
      )
    })
  );
@Effect()
  someEffect$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.UserLogIn),
    flatMap(_ => {  // get first data
      this.store.dispatch(new getData1());
      return of(_);
    }),
    flatMap(_ => {  // get second data
      this.store.dispatch(new getData2());
      return of(_);
    }),
    switchMap(action => { // run final action
      return [new finalAction()];
    }),
    catchError(() => of(new finalActionFailure()))
  );

然后执行finalAction()

@Effect()
  finalEffect$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.FinalActionAction),
    switchMap(action => {
      this.store.pipe(select(fromData.data1)).subscribe(data1 => {this.data1 = data1});
      this.store.pipe(select(fromData.data2)).subscribe(data1 => {this.data2 = data2});

  // this.data1, this.data2 are empty...

      return [new finalAction()];
    })
  );

someEffect$中,getData1getData2都在调用http请求并存储成功完成http调用的时间。

问题在于它不会等到数据保存到存储中。 而仅执行finalAction

我了解原因,因为flatMap等到getData1完成。但不是GetData1Success

在这种情况下,如何在finalEffect$时正确地从存储中获取数据?

谢谢。

编辑1:我已经尝试使用forkJoin。但是我不知道当存储在商店中时如何捕获数据。

1 个答案:

答案 0 :(得分:0)

我可以使用forkJoin解决。但是不确定这是否是一种干净的方法。

让我知道您的意见。

所以,我的解决方案是修改上面的第二个代码。

@Effect()
  someEffect$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.UserLogIn),
    switchMap(_ => {
      const data1 = this.httpClient.get(...);
      const data2 = this.httpClient.get(...);

      return forkJoin(data1, data2).pipe(
        tap(
         result => {
          // Here update data to the store.
          this.store.dispatch(GetData1Success(result[0]));
          this.store.dispatch(GetData2Success(result[1]));
         }

        )
      )

    }),
    switchMap(action => { // run final action
      return [new finalAction()];
    }),
    catchError(() => of(new finalActionFailure()))
  );

我已经有一个名为GetData1的动作,该动作可以获取data1,但由于我不知道如何捕捉data1保存在store中的瞬间,因此我无法使用此动作。

最终使用forkJoinswitchMap中手动调用http请求。