Issue
I had a nested Observable situation, and after some research I found that it’s best to use RxJS switchMap
.
For my case the first observable contains a Promise
, so I have to await the first subscription result before it’s passed to the second observable. Now the second Observable
is not being subscribed to and is returning an Observable
instead of subscribing to its results.
firstObservable(x) {
return this.productService.getProduct(x).pipe(
map(async result => {
this.productObject = {...result};
let timeVariable = await
this.distanceMatrixService.getTime(this.productObject, this.currentLocation);
return this.productObject;
})
}
async secondObservable(passedProductObject) {
const productObject = await passedProductObject;
return this.productService.getProductsByShop(productObject.store_id).pipe(
map(result => {
////STUFF that depends on the timeVariable
}));
}
chainingObservables(x) {
return this.firstObservable(x).pipe(
switchMap(async x => this.secondObservable(x)));
}
this.chainingObservables(this.passedData).subscribe(res => {
console.log("result", res);
})
result Observable {_isScalar: false, source: Observable, operator: MapOperator}
Any suggestion would be appreciated.
Solution
You could use RxJS from
function to convert the promise to an observable. After that a couple of switchMap
s with map
ought to suffice your requirement.
Try the following
this.productService.getProduct(x).pipe(
map(result => ({...result})),
switchMap(productObject =>
from(this.distanceMatrixService.getTime(productObject, this.currentLocation)).pipe(
map(timeVariable => ({
productObject: productObject,
timeVariable: timeVariable
}))
)
),
switchMap(({productObject, timeVariable}) =>
this.productService.getProductsByShop(productObject.store_id).pipe(
map(result => {
// stuff that depends on `timeVariable`
})
)
)
).subscribe(
res => {
console.log("result", res);
},
error => {
// handle error
}
);