Angular 在订阅之前,如何使用另一个请求循环http响应,扩展初始响应?
我正在使用Angular 6,我需要扩展从Http请求获得的联系人数组。每个联系人都有一个用户ID。我需要遍历contacts数组,根据userId发出另一个请求,这样我就可以使用用户的名字和姓氏扩展每个联系人。我必须提到,我必须在订阅之前完成它 contacts.service.tsAngular 在订阅之前,如何使用另一个请求循环http响应,扩展初始响应?,angular,rxjs,Angular,Rxjs,我正在使用Angular 6,我需要扩展从Http请求获得的联系人数组。每个联系人都有一个用户ID。我需要遍历contacts数组,根据userId发出另一个请求,这样我就可以使用用户的名字和姓氏扩展每个联系人。我必须提到,我必须在订阅之前完成它 contacts.service.ts findContacts(params: paramsModel): Observable<resultsModel> { const httpParams = this.getParams(
findContacts(params: paramsModel): Observable<resultsModel> {
const httpParams = this.getParams(params);
return this.http.get<resultsModel>('/getAllContacts', {
params: httpParams
}).pipe(
map((res: any) => res),
switchMap(res => {
const requests = res.map(contact => {
return this.http.get<any>('getUserById?userId=' + contact.userId).pipe(
map(userData => {
console.log(userData);
return _.extend(contact, {
userFirstName: user.firstName,
userLastName: user.lastName
});
})
);
});
return forkJoin(requests);
}),
map( res => {
return someFunction(res, params);
})
);
}
findContacts(参数:paramsModel):可观察{
const httpParams=this.getParams(params);
返回此.http.get(“/getAllContacts”{
参数:httpParams
}).烟斗(
映射((res:any)=>{
//在这里,我获得了所有联系人,但我需要遍历每个联系人,并根据userId发出另一个请求,以获取属于每个联系人的用户的信息
//res看起来像这样:
// {
// [
//id:1,
//名称:test1,
//用户ID:14
// ],
// [
//id:2,
//名称:test2,
//用户ID:9
// ],
// ..
// }
//我需要把它扩展成这样:
// {
// [
//id:1,
//名称:test1,
//用户ID:14,
//用户名:约翰,
//userLastName:Doe,
// ],
// [
//id:2,
//名称:test2,
//用户ID:9,
//用户名:Jane,
//userLastName:Doe,
// ],
// ..
// }
//我尝试了很多方法,但都不走运(包括flatMap、switchMap、使用链接观察对象,但在订阅之前我没有找到一个可以复制的循环示例,所以我很快就迷路了)。
//这是其中之一:
//res.map(联系人=>{
//this.http.get('getUserById?userId='+contact.userId).pipe(
//映射(用户=>{
////使用下划线进行扩展
//_uu.延伸(联系{
//userFirstName:user.firstName,
//userLastName:user.lastName
// });
//回接;
// })
// );
// });
返回一些函数(res、params);
})
);
}
contacts.data.ts
导出类联系人数据扩展数据{
构造函数(专用联系人服务:联系人服务){
超级();
}
负载触点(
params:paramsModel
) {
this.loadingSubject.next(true);
this.contactsService.findContacts(params).pipe(
轻触(res=>{
this.entitySubject.next(res.items);
this.paginatorTotalSubject.next(res.totalCount);
}),
catchError(err=>of(新结果模型([],err)),
完成(()=>this.loadingSubject.next(false))
).subscribe();
}
}
contacts-list.component.ts
导出类ContactsListComponent实现OnInit{
contactsData:contactsData;
恩戈尼尼特(){
const params=new paramsModel();
此.contactsData.loadContacts(参数);
}
}
解决方案在MichałTkaczyk的帮助下:
contacts.service.ts
findContacts(params: paramsModel): Observable<resultsModel> {
const httpParams = this.getParams(params);
return this.http.get<resultsModel>('/getAllContacts', {
params: httpParams
}).pipe(
map((res: any) => res),
switchMap(res => {
const requests = res.map(contact => {
return this.http.get<any>('getUserById?userId=' + contact.userId).pipe(
map(userData => {
console.log(userData);
return _.extend(contact, {
userFirstName: user.firstName,
userLastName: user.lastName
});
})
);
});
return forkJoin(requests);
}),
map( res => {
return someFunction(res, params);
})
);
}
findContacts(参数:paramsModel):可观察{
const httpParams=this.getParams(params);
返回此.http.get(“/getAllContacts”{
参数:httpParams
}).烟斗(
映射((res:any)=>res),
开关映射(res=>{
const requests=res.map(contact=>{
返回此.http.get('getUserById?userId='+contact.userId).pipe(
映射(userData=>{
console.log(userData);
返回扩展(联系{
userFirstName:user.firstName,
userLastName:user.lastName
});
})
);
});
返回forkJoin(请求);
}),
地图(res=>{
返回一些函数(res、params);
})
);
}
首先将rxjs映射更改为switchMap,然后您可以迭代第一个可观察的数据,并创建一个可观察的数组,该数组可以在switchMap中作为forkJoin返回
代码:
您可以尝试这段代码,虽然我不建议创建这么多请求,但更好的方法是从API调用获取这些数据
编辑:
正如Oles Savluk所提到的,switchMap中的resultSelector已被弃用,因此您可以在forkJoin中的每个可见项添加另一个管道:
switchMap(res => {
const requests = res.map(contact => {
return this.http.get<any>('getUserById?userId=' + contact.userId).pipe(
map(userData => {
return { ...contact, ...userData };
})
);
});
return forkJoin(requests);
})
switchMap(res=>{
const requests=res.map(contact=>{
返回此.http.get('getUserById?userId='+contact.userId).pipe(
映射(userData=>{
返回{…联系人,…用户数据};
})
);
});
返回forkJoin(请求);
})
获取所有联系人->将联系人映射到可观察的联系人->它发出每个项目->使用每个项目形成一个http请求->在该http请求上,通过管道映射来获取格式结果,使用联系人和用户详细信息->使用toArray()将其收集为数组->订阅。返回所需输出的数组
this.http.get<resultsModel>('/getAllContacts', { params: httpParams}).pipe(
mergeMap(contacts=> from(contacts)),
concatMap((contact) => this.http.get<any>('getUserById?userId=' + contact.userId).pipe(
map((userDetails) => {
contact['userFirstName']=userDetails['userFirstName'];
contact['userLastName']=userDetails['userLastName'];
return contact
}))),
toArray()).subscribe(res => console.log(res));
this.http.get('/getAllContacts',{params:httpParams}).pipe(
合并映射(联系人=>from(联系人)),
concatMap((contact)=>this.http.get('getUserById?userId='+contact.userId).管道(
地图((用户详细信息)=>{
联系人['userFirstName']=userDetails['userFirstName'];
this.http.get<resultsModel>('/getAllContacts', { params: httpParams}).pipe(
mergeMap(contacts=> from(contacts)),
concatMap((contact) => this.http.get<any>('getUserById?userId=' + contact.userId).pipe(
map((userDetails) => {
contact['userFirstName']=userDetails['userFirstName'];
contact['userLastName']=userDetails['userLastName'];
return contact
}))),
toArray()).subscribe(res => console.log(res));