【问题标题】:Angular RxJS map <Observable[]> with api request带有 api 请求的 Angular RxJS 映射 <Observable[]>
【发布时间】:2020-04-13 17:51:33
【问题描述】:

在我的一个路由解析器中,我想获取 API 调用返回的动物 (Animal[]) 列表。对于每一种动物,我都需要一个额外的 API 调用来获取品种名称。 我试过这个:

return this.apiService.get('/api/v1/website/' + environment.web_id + '/useraccount/' + user.id + '/animal').pipe(
  map(animals => animals.map(animalObs => {
    // return animalObs;
    return animalObs.pipe(
      map((animal: Animal) => {
        animal.ani_breed = this.breedService.get(animal.anb_id).pipe(
          map(breed => {
            return breed.anb_name;
          })
        );
        return animal;
      }),
    );
  })),
);

但编译时出现错误:类型“Observable”不可分配给类型“字符串”。 [2322]

我想我遗漏了一些东西...请帮忙!

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    实际实现取决于您是要按顺序运行请求还是并行运行请求,但您可以执行以下示例:

    this.apiService.get('/api/v1/website/' + environment.web_id + '/useraccount/' + user.id + '/animal').pipe(
      mergeMap(animals => {
        const animals$ = animals.map(animal => this.breedService.get(animal.anb_id).pipe(
          map(breed => {
            animal.ani_breed = breed;
            return animal;
          })
        ))
    
        return forkJoin(...animals$);
      }),
    );
    

    【讨论】:

      【解决方案2】:

      我认为您需要的是一个mergeMap,它将您当前的请求合并到另一个请求,该请求将使用forkJoin 请求所有返回的动物并将它们组合在一起。

        getAnimals = () => this.apiService.get('/api/v1/website/' + environment.web_id + '/useraccount/' + user.id + '/animal').pipe(
          mergeMap(animals =>
            Observable.create((observer: Observer<any[]>) => {
              const animals$ = animals.map(
                animal => this.breedService.get(animal.anb_id).pipe(
                  map(breed => {
                    return {
                      ...animal,
                      breed_name: breed.anb_name
                    }
                  })
                )
              );
      
              forkJoin(animals$).subscribe(result => {
                observer.next(result);
                observer.complete();
              });
            }))
        );
      

      更多关于 forkJoin 和 mergeMap

      https://www.learnrxjs.io/operators/combination/forkjoin.html

      https://www.learnrxjs.io/operators/transformation/mergemap.html

      编辑

      您想要获取动物及其品种名称的方法是使用扩展运算符返回所有动物属性并在其旁边分配面包名称。

              map(breed => {
                return {
                  ...animal,
                  breed_name: breed.anb_name
                }
              })
      

      最终编辑

      扩展运算符允许您枚举所有对象的属性。它与下面的代码具有相同的输出,但过程不同。

        map(breed => {
          animal.breed_name = breed.anb_name;
          return animal;
        })
      

      【讨论】:

      • 嗨@Riyens,感谢您的回复。这样做只是给我品种名称作为结果
      • @LouisRocher 这就是我在您的实施中看到的。我可以知道你的预期输出是什么吗?
      • 我想要一个动物数组,其中的品种名称作为一个动物对象的字符串。感谢您的宝贵时间
      • 已更新。我希望我解释的所有内容都有意义/理解,以便其他人在遇到相同问题时也可以应用它
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      相关资源
      最近更新 更多