Angular 当结果为数组时合并两个api调用结果

Angular 当结果为数组时合并两个api调用结果,angular,Angular,我有一个工作的angular代码,它合并了两个API结果,其中第二个调用依赖于第一个调用。这是一个简单的联接操作: class myPerson { constructor( public name: string, public planet: string){} } let person = http.get<myPerson[]>('https://swapi.co/api/people/1/') .pipe( switchMap(

我有一个工作的angular代码,它合并了两个API结果,其中第二个调用依赖于第一个调用。这是一个简单的联接操作:

class myPerson {
  constructor(
     public name: string,
     public planet: string){}
}

let person = http.get<myPerson[]>('https://swapi.co/api/people/1/')
  .pipe(
    switchMap(
      person => http.get(person['homeworld'])
        .pipe(
          map(planet => 
          {
            return new myPerson(person['name'], planet['name'])
          })
        )
    )
  )

  person.subscribe( 
    result => console.log(result)
  )

然而,当涉及到扩展它以处理来自第一个API调用()的结果数组时,我完全陷入了困境。我最接近的例子如下:

  tmpObs: Observable<any[]>


  http.get<any[]>('https://swapi.co/api/people/')
  .pipe(
    switchMap(people => 
    {
      let planets = people['results'].map( person => {
        return http.get(person['homeworld']) 
      })
      this.tmpObs = of(people)
      return forkJoin(planets)  
    })
  ).subscribe( planets =>
  {
    this.tmpObs.subscribe( people => {
      console.log(people, planets)
    })
  }
)
tmpObs:可观察
http.get('https://swapi.co/api/people/')
.烟斗(
切换地图(人=>
{
让行星=人['results'].地图(person=>{
返回http.get(person['homeworld'])
})
this.tmpObs=of(人)
返回分叉连接(行星)
})
).订阅(行星=>
{
this.tmpObs.subscribe(people=>{
console.log(人、行星)
})
}
)
但是使用临时observables数组似乎是错误的,我需要的信息是API调用的订阅。如何创建myPerson的可观察数组?帮帮我,你是我唯一的希望。

这里是救援:

您已接近您的解决方案。唯一的问题是你没有得到两个回报。我会在以下方面做更多的事情(不确切,因为我不能100%确定你的目标):


这是我将采取的方法

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class StarWarsService {

    constructor(private http: HttpClient) { }
    getPeople() {
        return this.http.get<any>('https://swapi.co/api/people/').pipe(
            map(people => {
                people.results.map(person => this.http.get<any>(person.homeworld).subscribe(
                    homeworld => person.planet = homeworld
                ));
                return people;
            })
        );
    }
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpClient};
从“rxjs/operators”导入{map};
@注射的({
providedIn:'根'
})
导出类StarWarsService{
构造函数(私有http:HttpClient){}
getPeople(){
返回此.http.get('https://swapi.co/api/people/)。烟斗(
地图(人物=>{
people.results.map(person=>this.http.get(person.homeworld.subscribe)(
homeworld=>person.planet=homeworld
));
还人,;
})
);
}
}
该服务通过http调用获取人物,然后循环(使用map)通过这些结果获取家庭世界,并将其分配给每个人的planet属性

下面是如何在组件中使用上述服务

import { Component, OnInit } from '@angular/core';
import { StarWarsService } from '../shared/star-wars.service';
import { Observable } from 'rxjs';

@Component({
    selector: 'app-star-wars',
    template: `<div *ngIf="people$ | async as people">
      <pre>{{ people | json }}</pre>
    </div>`,
    styleUrls: ['./star-wars.component.css']
})
export class StarWarsComponent implements OnInit {
    people$: Observable<any>;
    constructor(private starWarsService: StarWarsService) { }

    ngOnInit() {
        this.people$ = this.starWarsService.getPeople();
    }

}
从'@angular/core'导入{Component,OnInit};
从“../shared/starwars.service”导入{StarWarsService};
从“rxjs”导入{Observable};
@组成部分({
选择器:“应用程序星球大战”,
模板:`
{{people | json}}
`,
样式URL:['./starwars.component.css']
})
导出类StarWarsComponent实现OnInit{
人:可观察的;
构造函数(专用starWarsService:starWarsService){}
恩戈尼尼特(){
this.people$=this.starWarsService.getPeople();
}
}

模板中的异步管道处理订阅/取消订阅。很好用。

谢谢你的回复,但我不明白。我不认为我能像你建议的那样做forkJoin,因为行星的获得取决于首先得到的人。这让我抓狂,因为用SQL术语来说,这是一个非常简单的任务:从people pe、planets pl中选择pe.name、pl.name,其中pe.homeworld=pl.name(或者类似的东西)。我想要(应该是)对我的工作示例进行一个简单的扩展,从中可以得到myPerson数组,而不是单个数组。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class StarWarsService {

    constructor(private http: HttpClient) { }
    getPeople() {
        return this.http.get<any>('https://swapi.co/api/people/').pipe(
            map(people => {
                people.results.map(person => this.http.get<any>(person.homeworld).subscribe(
                    homeworld => person.planet = homeworld
                ));
                return people;
            })
        );
    }
}
import { Component, OnInit } from '@angular/core';
import { StarWarsService } from '../shared/star-wars.service';
import { Observable } from 'rxjs';

@Component({
    selector: 'app-star-wars',
    template: `<div *ngIf="people$ | async as people">
      <pre>{{ people | json }}</pre>
    </div>`,
    styleUrls: ['./star-wars.component.css']
})
export class StarWarsComponent implements OnInit {
    people$: Observable<any>;
    constructor(private starWarsService: StarWarsService) { }

    ngOnInit() {
        this.people$ = this.starWarsService.getPeople();
    }

}