0

我需要调用一个返回对象数组的 api。然后我需要遍历所有对象并使用每个对象的 id 我需要调用另一个 api。然后我打算将数据保存在一个数组中并订阅,以便我可以访问包含来自两个 api 调用的数据的自定义数组。但是它对我不起作用。

我需要来自两个 api 调用的组合数据,但是在我创建的结果数组中,来自第二个 api 的数据显示为可观察的,当我尝试使用它们时出现未定义的错误。任何帮助将不胜感激。

   this.apiService.getIntakeEvents(90430)
.pipe(mergeMap((res: any)=>{
  const allData =[];
  for(const item of res) {
    let courseInfo = this.apiService.getSpecificCourse(item.courseId)
    allData.push({...item, courseInfo})
  }
  console.log(allData)
  return allData;
}))
.subscribe(res=> console.log(res))
4

3 回答 3

1

您需要使用组合运算符,如forkJoin,combineLatestzip并行触发多个可观察对象。鉴于它是一个 API 调用,我会说它forkJoin更适合这里,因为它仅在所有源都完成后才会发出。一个简短的区别 b/n 他们在这里

您还需要使用Array#map将对象数组转换为 HTTP 调用数组。之后,您可以map对每个可观察的源使用 RxJS 运算符,以将其转换回具有修改后courseInfo属性的对象。

this.apiService.getIntakeEvents(90430).pipe(
  mergeMap((res: any) => 
    forkJoin(
      res.map(item => this.apiService.getSpecificCourse(item.courseId)).pipe(
        map(courseInfo => ({ ...item, courseInfo: courseInfo }))
      )
    )
  )
).subscribe(
  next: (res: any) => {
    console.log(res)
  },
  error: (error: any) => {
    // handle error
  }
);

更新:API 调用对象中的多个属性

要从外部 observable 更新对象中的多个属性,您可能必须使用forkJoin包装在外部的多个 s forkJoin。这当然只是一种方法,可能还有其他更好的方法。

例子

this.apiService.getIntakeEvents(90430).pipe(
  mergeMap((res: any) => 
    forkJoin({
      courses: forkJoin(res.map(item => this.apiService.getSpecificCourse(item.courseId))),
      names: forkJoin(res.map(item => this.apiService.getSpecificName(item.courseId))),
      ages: forkJoin(res.map(item => this.apiService.getSpecificAge(item.courseId)))
    }).pipe(map(({courses, names, age}) => 
      res.map((item, index) => ({
        ...item,
        courseInfo: courses[index],
        name: names[index],
        age: ages[index]
      })
    ))
  )
).subscribe(
  next: (res: any) => {
    console.log(res)
  },
  error: (error: any) => {
    // handle error
  }
);
于 2021-04-13T06:45:25.467 回答
1

我们需要使用几个 RXJS 操作符来得到你想要的。

  • 我们可以使用mergeMap扁平化内部可观察对象
  • 然后我们使用combineLatest从每个 API 调用中获取最新结果
  • 然后我们map在每个单独的 API 调用上使用它来返回item和它是相关的courseInfo
this.apiService
      .getIntakeEvents(90430)
      .pipe(
        mergeMap((items) => {
          return items.map((item) =>
            this.apiService.getSpecificCourse(item.courseId).pipe(
              map((courseInfo) => {
                return {
                  item,
                  courseInfo,
                };
              })
            )
          );
        })
      )
      .subscribe((res) => console.log(res));
于 2021-04-13T06:39:07.137 回答
0

你将不得不转换

this.apiService.getSpecificCourse(item.courseId);

从一个可观察的到一个承诺(你如何做取决于你的 rxjs 版本,它包含在那个链接中)。一旦它被转换为一个承诺,你就可以调用 .then() ,它允许你从回调中返回一个实际值。一个 observable 只允许你订阅,它不允许你从回调中返回一个值。

所以如果你有最新的 rxjs。你可以做:

let courseInfo = lastValueFrom(this.apiService.getSpecificCourse(item.courseId)).then((info) => info);

我认为应该有效

于 2021-04-13T06:55:28.893 回答