如何在保留初始api响应数据的同时链接RXJS Angular httpclient可观察到的api调用
我有两个api调用,location和person,location是一个包含person slug的位置数组。对于每个位置,我都会让slug调用personapi响应。
问题是,我需要保存初始位置调用的数据,比如他们的城市,还需要保存personapi调用中的人名。
根据我所读到的内容,您可以通过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))
};
是否保存locationapi调用数据city以添加到reduce函数中的最终响应数组?
一种解决方案是两个api调用,首先保存一个位置数据数组,然后为每个联系人调用一个api,并修改现有的位置数据数组。
您可以使用forkJoin
运算符并行调用它们,而不是单独触发每个this.http.get('fullPersonApiUrl' + value['person-slug'])
。然后,您可以使用RxJSmap
运算符以及Arraymap
和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
只有在所有源可观测性完成时才会发射。请求将是并行的,大多数浏览器对单个域的并发请求数量有严格限制。如果遇到这个问题,您可以研究RxJS
bufferCount
运算符来生成缓冲的并行请求。forkJoin(values.map(value => 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',
},
...
]