订阅对每个项目都有一个内部订阅

时间:2018-10-02 19:13:43

标签: angular rxjs rxjs6

我提供以下服务:

public loadMatchAnalysis(clientId: string): void {
    this.logger.info(`Calling matchAnalysisService to get everything for the 'Match Analysis' page`);

    this.matchAnalysisService.getMatchAnalysis(clientId).subscribe(
      (matches: MatchAnalysis[]) => {
        matches.forEach(match => {
          forkJoin(
            this.matchAnalysisService.getMappings(clientId, match.id),
            this.matchAnalysisService.getCalculationMethods(clientId, match.id)
          ).subscribe(([mappings, calculations]) => {
            match.mappings = mappings.filter(m => m.id === match.id);
            match.children = calculations.filter(c => c.id === match.id);

            console.log('mappings', mappings);
            console.log('calculations', calculations);
            console.log('matches', matches);
          });
        });

        //THIS ONLY NEEDS TO BE CALLED ONCE
        new GetMatchAnalysisLoadedAction({ data: matches }).dispatch();
      },
      (error: HttpErrorResponse) => {
        new GetMatchAnalysisLoadedAction({ error: error }).dispatch();
      }
    );
  }

我要完成的工作:

我需要进行API调用,该调用将返回matches的列表。每个match都有一个id,以便进行两个新的API调用。如您所见,我正在使用forkJoin来执行调用,并且当我取回数据时,正在使用所需的数据来修改matches。完成所有操作后,我需要使用所有数据(GetMatchAnalysisLoadedAction())来调用matches

除了只调用一次GetMatchAnalysisLoadedAction()以外,上面的代码大部分都是有效的,而且我理解为什么会发生。

是否有一些RXJS魔术可以很好地完成所有这些工作?

1 个答案:

答案 0 :(得分:1)

我这样解决了它:

  public loadMatchAnalysis(clientId: string): void {
    this.logger.info(`Calling matchAnalysisService to get everything for the 'Match Analysis' page`);

    this.matchAnalysisService
      .getMatchAnalysis(clientId)
      .pipe(
        switchMap(matches => {
          const mappings = matches.map(match => this.matchAnalysisService.getMappings(clientId, match.id));
          const calculations = matches.map(match =>
            this.matchAnalysisService.getCalculationMethods(clientId, match.id)
          );

          return forkJoin(of(matches), ...mappings, ...calculations);
        })
      )
      .subscribe(([matches, mappings, calculations]: [MatchAnalysis[], MatchAnalysisMapping[], Calculation[]]) => {
        matches.forEach(match => {
          match.mappings = mappings.filter(m => m.id === match.id);
          match.children = calculations.filter(c => c.id === match.id);
        });

        new GetMatchAnalysisLoadedAction({ data: matches }).dispatch();
      });
  }