将嵌套的 AngularJS 服务转换为 Angular 可观察服务

convert nested AngularJS service to Angular Observable service

我有一些 AngularJS(1.5 之前)服务在我们正在 Angular(11) 中重建的项目中使用嵌套调用。 这些服务使用嵌套调用,但我不知道如何使用 RXJS 重建它们。

任何帮助或详细链接来了解我如何获得我需要的结果都会很棒。 到目前为止,我还没有找到任何可以帮助我理解如何解决这个问题的东西。

这是原来的服务:

function getBalanceGroups() {
            return $http.get(url.format("/accounts/{{accountId}}/balance-groups", $stateParams))
                .then(function (response) {
                    _.each(response.data, function (item) {
                        getBalanceViews(item.accountBalanceGroupId)
                            .then(function (balanceViewData) {
                                item.balanceViews = _.sortBy(balanceViewData, function (view) {
                                    return (view.balanceViewId === item.totalIndebtednessViewId) ? 0 : 1;
                                });
                                _.each(item.balanceViews, function (view) {
                                    getBalanceSegments(view.accountBalanceViewId)
                                        .then(function (balanceSegmentData) {
                                            view.balanceSegments = balanceSegmentData;
                                            view.totalBalance = 0;
                                            view.totalBalance = _.sumBy(view.balanceSegments, "balance");
                                        });
                                });
                            });
                    });
                    response.data = _.sortBy(response.data, function (item) {
                        return (item.isActive && item.isPrimary) ? 0 : 1;
                    });
                    return new LinkedList(response.data);
                }, function (error) {
                    $log.error('Unable to return balance group for the balanceChiclet');
                });
        }

这是我目前所拥有的:(不工作 - 它正在 returning 最终的 api 数据响应,我需要使用数据来使用数据修改之前的响应和 return 修改后的数据。不知道如何 )

getBalanceGroups(accountId: number | string): Observable<any> {
    let balGroupsUrl = `/accounts/${accountId}/balance-groups`;
    return this.http.get(`${this.baseUrl}${balGroupsUrl}`).pipe(
      mergeMap( (groups: any) => groups),
      flatMap((group:any) => {
        group.balanceViews = [];
        
        return this.getBalanceViews( group.accountBalanceGroupId, group )

      }),
      mergeMap( (views: any) => views),
      flatMap((views: any) => {
        return this.getBalanceSegments( views.accountBalanceViewId )
      }),

      catchError((err) => of(err) ),

      tap( groups => console.log('groups: 3:', groups) ),
    )

  }

private getBalanceViews(accountBalanceGroupId: number | string, group): Observable<any> {
    let balViewsUrl = `/balance-groups/${accountBalanceGroupId}/balance-views`;
    return this.http.get(`${this.baseUrl}${balViewsUrl}`);
  }

  private getBalanceSegments(accountBalanceViewId: number | string): Observable<any> {
    let balSegUrl = `/balance-views/${accountBalanceViewId}/balance-segments`;
    return this.http.get(`${this.baseUrl}${balSegUrl}`);
  }

  1. 您可以使用 forkJoin 来并行触发多个请求,而不是 mergeMap + flatMap(顺便说一句,它们是同义词)。
  2. 鉴于请求的性质,您可能必须使用多个嵌套 forkJoin
  3. 虽然我已经使用 Array#reduce 转换了 loadash sumBy,但我留下了 sort 不完整的供您完成。

尝试以下方法

getBalanceGroups(): Observable<any> {
  return this.http.get(`/accounts/${accountId}/balance-groups`, { params: stateParams }).pipe(
    switchMap((response: any) =>
      forkJoin(
        response.data.map((item: any) => 
          getBalanceViews(item.accountBalanceGroupId, item).pipe(
            map((balanceViewData: any) => ({
              ...item,
              balanceViews: balanceViewData.sort()            // <-- incomplete
            })),
            switchMap((item: any) => 
              forkJoin(
                item.balanceViews.map((view: any) =>
                  getBalanceSegments(view.accountBalanceGroupId).pipe(
                    map((balanceSegmentData: any) => ({
                      ...item,
                      balanceSegments: balanceSegmentData,
                      totalBalance: view.balanceSegments.reduce((acc, curr) => acc += curr['balance'], 0)
                    }))
                  )
                )
              )
            )
          )
        )
      )
    ),
    map((response: any) => ({
      ...response,
      response.data: response.data.sort()                      // <-- incomplete
    })),
    catchError((error: any) => {
      console.error('Unable to return balance group for the balanceChiclet');
      return of(error);
    })
  );
}