Angular 从2个API创建对象
我试图用来自2个API的数据创建一个对象。我的问题是,当我使用第二个api创建属性时,它是可观察的。有没有一种方法可以解开“嵌套”的可观察对象Angular 从2个API创建对象,angular,rxjs,Angular,Rxjs,我试图用来自2个API的数据创建一个对象。我的问题是,当我使用第二个api创建属性时,它是可观察的。有没有一种方法可以解开“嵌套”的可观察对象 getUpcomingRes():可观察{ 常数upcomingResHolder=[]; 返回此.config.connectReservations(this.hostID).pipe( 地图((resData:Reservation[])=>{ for(resData的常数){ const arrivalDate=新日期(res.dateArriv
getUpcomingRes():可观察{
常数upcomingResHolder=[];
返回此.config.connectReservations(this.hostID).pipe(
地图((resData:Reservation[])=>{
for(resData的常数){
const arrivalDate=新日期(res.dateArrival);
const today=新日期();
如果(到达日期>今天){
const flightArrivalData=this.config.getFlightInformation(res.flightArrivalID).pipe(
映射(快照=>{
返回快照.map(
快照=>{
返回{…snap};
}
);
})
);
常量ob={…res,flighArrData:flightArrivalData};
向上推动支架(ob);
}
}
返回upcomingResHolder.sort((a,b)=>b.dateArrival-a.dateArrival);
}));
}
如果要同时进行两个api调用,请使用CombineTest
combineLatest(call1$, call2$).subscribe(([response1, response2]) => {
});
如果要在一秒钟内使用一个api调用的结果,请使用switchMap
call1$.pipe(switchMap(response1 => call2(response.property))).subscribe(response2 => {
});
<>为了可读性,请考虑分开一些子需求。我在我的例子中就是这样做的。要访问内部可观察对象,您需要使用更高的贴图功能,如exhaustMap、switchMap、concatMap。。。我希望我的例子对你来说是清楚的
getUpcomingRes(): Observable<Reservation[]> {
const today = new Date();
return this.config.connectReservations(this.hostID).pipe(
map(reservations => reservations.filter(reservation => new Date(reservations.dateArrival) > today)),
map(reservations => reservations.sort((a, b) => b.dateArrival - a.dateArrival)),
switchMap(reservations => forkJoin([of(reservations), ...reservations.map(reservation => this.config.getFlightInformation(reservation.flightArrivalID))])),
map(([reservations, ...snaps]) => reservations.map((reservation, i) => ({ ...reservation, flighArrData: snaps[i] }))),
);
}
getUpcomingRes():可观察{
const today=新日期();
返回此.config.connectReservations(this.hostID).pipe(
映射(预订=>reservations.filter(reservation=>newdate(reservations.Date-arrival)>day)),
map(reservations=>reservations.sort((a,b)=>b.dateArrival-a.dateArrival)),
switchMap(reservations=>forkJoin([of(reservations),…reservations.map(reservations=>this.config.getFlightInformation(reservation.flightArrivalID))),
map(([reservation,…snaps])=>reservations.map((reservation,i)=>({…reservation,flighardata:snaps[i]})),
);
}
由于没有订阅flightArrData
可见,因此可以观察到flightArrData
属性,但是不鼓励嵌套订阅的这种行为,可以使用一些简单的操作符,如mergeMap
和switchMap
来避免这种行为
我已经重构了您的示例,以了解我将如何处理此问题:
getUpcomingRes(): Observable<Reservation[]> {
const today = new Date();
return this.config.connectReservations(this.hostID).pipe(
switchMap(reservations =>
from(reservations).pipe(
filter(({ dateArrival }) => new Date(dateArrival) > today),
this.populateReservationSnaps(),
toArray()
)
),
map(reservations =>
reservations.sort((a, b) => a.dateArrival - b.dateArrival)
)
);
}
populateReservationSnaps(): MonoTypeOperatorFunction<Reservation> {
return (source: Observable<Reservation>) =>
source.pipe(
mergeMap(reservation =>
this.config
.getFlightInformation(reservation.flightArrivalID)
.pipe(map(snaps => ({ ...reservation, flightArrData: snaps })))
)
);
}
getUpcomingRes():可观察{
const today=新日期();
返回此.config.connectReservations(this.hostID).pipe(
switchMap(预订=>
从(预订处)开始(
过滤器({dateArrival})=>new Date(dateArrival)>today),
此.populateServationSnaps(),
toArray()
)
),
地图(预订=>
reservations.sort((a,b)=>a.dateArrival-b.dateArrival)
)
);
}
populateReservationSnaps():MonoTypeOperatorFunction{
返回(来源:可观察)=>
源管道(
合并地图(预订=>
this.config
.getFlightInformation(reservation.flightArrivalID)
.pipe(映射(快照=>({…保留,flightArrData:snaps})))
)
);
}
让我们一步一步地克服它:
首先,populateReservationSnaps
是一个简单的,返回类型:
MonoTypeOperatorFunction
仅表示此运算符作用于保留
对象流,并返回一个。
其逻辑非常简单,对于每个保留
调用第二个API并用快照填充它
其次,getUpcomingRes
执行以下操作:
- 检索保留数组并使用
运算符将其展平from
- 过滤不需要的预订-相当于您的
语句if
- 用自己的快照填充每个
保留
- 将保留累积到数组并对其排序
展平不是必须的,我只是发现在展平流上操作更容易。为什么需要执行
returnsnaps.map(snap=>{return{…snap};})代码>非常感谢!