【问题标题】:Chain api calls and save data from initial api result链式 api 调用并保存初始 api 结果中的数据
【发布时间】:2020-08-19 16:03:34
【问题描述】:

如何在保留初始 api 响应数据的同时链接 RXJS Angular httpclient observable api 调用?

我有两个 api 调用,location 和 person,location 是一个包含 person slug 的位置数组。对于每个位置,我都会让 slug 调用人员 api 响应。

问题是我需要保存初始位置调用的数据,比如他们的城市,还需要保存人员 api 调用中的人名。

根据我的阅读,您可以通过 mergeMap 链接 api 请求,但结果值只会是最新的 api 数据。

位置 API 调用数据

[
  {
    city: 'mycity',
    person-slug: 'person-x',
  },
  {
    city: 'yourcity',
    person-slug: 'person-y',
  },
]

Api 提供者(RXJS Api 调用)

private http: HttpClient; // Angular Http Client

const req = this.http.get<Array<any>>('fullLocationApi')
  .pipe(
    // Split up initial array of objects response into stream of objects
    mergeMap(val => {
      return val;
    }),

    mergeMap(val => {

      // Call the second Api to get the person details
      const personSlug = val.person-slug;
      const personUrl = 'fullPersonApiUrl' + personSlug;

      return this.http.get(personUrl);
    }),
    // Combine together the single stream into an array
    // Only saves the city api call data, doesn't save the location city
    reduce((dataArr, data) => {
      return dataArr.concat(data);
    }, []),

不幸的是,在合并地图中保存更多数据而不只是 api 响应之类的东西要么不起作用,要么不会订阅地图结果。

     // Doesn't work, but would be ideal, that way there's data saved from the old call as well
     mergeMap(val => {

      const personSlug = val.person-slug;          
      const personUrl = 'fullPersonApiUrl' + personSlug;

      return {
        old: val,
        contact: this.http.get(personUrl))
      };

是否有保存位置api调用数据城市添加到reduce函数中的最终响应数组?

一种解决方案是两次 api 调用,首先保存一个位置数据数组,然后为每个联系人调用一个 api 并修改现有的位置数据数组。

【问题讨论】:

  • 你可以像this.http.get(personUrl)).pipe(map(res =&gt; hereCombine(res + locDetails)))一样管你的this.http.get(personUrl))

标签: angular api http rxjs


【解决方案1】:

您可以使用forkJoin 运算符并行调用它们,而不是单独触发每个this.http.get('fullPersonApiUrl' + value['person-slug'])。然后,您可以使用 RxJS map 运算符以及 Array map 和 Object.assign 方法返回第一个和第二个请求的组合结果。

试试下面的

const req = this.http.get<Array<any>>('fullLocationApi').pipe(
  switchMap(values => {
    return forkJoin(values.map(value => this.http.get('fullPersonApiUrl' + value['person-slug']))).pipe(
      map(contacts => contacts.map((contact, index) => Object.assign(values[index], {contact: contact})))
    );
  })
);

注意:

  • forkJoin 只会在所有源 observables 完成时发出。

  • 请求将是并行的,并且大多数浏览器对单个域的并发请求数量有硬性限制。如果你遇到这个问题,你可以查看 RxJS 的 bufferCount 运算符来制作 buffered parallel requests。

  • forkJoin(values.map(value =&gt; this.http.get('fullPersonApiUrl' + value['person-slug']))) 的结果将是一个表单数组

[
  result from this.http.get('fullPersonApiUrl' + 'person-x'), 
  result from this.http.get('fullPersonApiUrl' + 'person-y'),
  ...
];
  • 最终结果将是表单对象的数组
[
  {
    contact: result from this.http.get('fullPersonApiUrl' + 'person-x')
    city: 'mycity',
    person-slug: 'person-x',
  },
  {
    contact: result from this.http.get('fullPersonApiUrl' + 'person-y')
    city: 'yourcity',
    person-slug: 'person-y',
  },
  ...
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2014-04-16
    • 2019-09-03
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多