【问题标题】:Angular map http response value with another http callAngular 映射 http 响应值与另一个 http 调用
【发布时间】:2019-01-30 09:18:09
【问题描述】:

我有一个如下所示的 http 调用:

public getCommuneByCode(code: string): Observable<Commune> {
  return this.http.get<Commune[]>(ApiUrl);
}

公社模式如下:

export interface Commune {
  code: string;
  departement: string;
  postalCode: string;
}

我有另一个 http 调用来获取用户数据:

public getUserData(id: number): Observable<User> {
  return this.http.get<User>(ApiUrl);
}

用户模型:

export interface User {
  id: number;
  name: string;
  libAddress: string;
}

我想做的是使用 getCommuneByCode 服务的响应来设置 libAddress 属性,如下所示:

this.service.getUserData(id).pipe(
    map((user: User) => {
      user.libAddress = this.service.getCommuneByCode(code).pipe(
        map(commune => `${commune.postalCode} - ${commune.departement}`)
      );
      return user;
    })
  ).subscribe((userWithLibAddress) => {
    // user object with all data and libAddress property is equal to ex: 99999 - DepartementXX
  })

但正如我所料,它会返回一个可观察的答案,我不知道如何做才能得到答案。感谢您的帮助

【问题讨论】:

    标签: javascript angular rxjs httpclient


    【解决方案1】:

    这个应该可以的。如果您需要解释,请提出!

    forkJoin(
      this.service.getUserData(id),
      this.service.getCommuneByCode(code)
    ).pipe(
      map(([user, commune]) => ({ ...user, libAdress: `${commune.postalCode} - ${commune.departement}`})
    );
    

    编辑如果您必须按顺序拨打电话:

    this.service.getUserData(id).pipe(
      switchMap(user => this.service.getCommuneByCode(user.code)).pipe(
        map(commune => ({ ...user, libAdress: `${commune.postalCode} - ${commune.departement}`}))
      )
    )
    

    【讨论】:

    • 我考虑过 forkjoin,但问题是如果 getCommuneByCode 因任何原因失败,它们都失败了,这不是我想要的。
    • 即使没有forkJoin,如果您有错误,那么您的代码将无法工作。这就是错误的原则,他们不会做你所期望的。这就是为什么你有像catchError 这样的运算符来处理出现的错误。您的论点并没有真正加起来,并且肯定不是投反对票的理由:您的问题是关于组成一个对象,而不是关于如何管理错误。
    • 我没有投反对票,当我看到它时,我和你一样感到惊讶,我喜欢你的解决方案,所以我没有理由投反对票。感谢您对 catchError 的回答,事实上,无论我使用什么运算符,它都会以相同的方式处理
    • 好吧,那我的错!没错,您无论如何都需要catchError。在我看来,forkJoin 比使用 [merge/switch/concat]Map 运算符更干净,因为它们会添加缩进级别并产生相同的结果。
    • 哦,我的糟糕,我现在确实记得为什么我实际上不能使用 forkJoin,我忘记指定我的错误,调用 getCommuneByCode 服务的代码是基于用户服务响应的。我试图为这个问题简化我的 api,但我错过了这个细节。
    【解决方案2】:

    您可以使用 MergeMap。例如,您可以尝试这样的事情-

    this.service.getUserData(id).pipe(
        mergeMap( (user:User) => this.service.getCommuneByCode(code).pipe(
            map(commune => user.libAddress = `${commune.postalCode} - ${commune.departement}`)
          )
        )
      ).subscribe();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      • 2017-10-27
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      相关资源
      最近更新 更多