Angular 当结果为数组时合并两个api调用结果
我有一个工作的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(
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();
}
}