I make an api call which returns an array. I need to loop over this array and perform a new request per item. The following code works fine:
return this.expeditionService.getTranssmartBookingXml(request).pipe(
concatMap((response) => {
return from(response.barcodes).pipe(
concatMap((barcode) => {
return this.expeditionService.saveTranssmartBarcode({
...saveBarcodeRequest,
barcode: barcode,
});
})
);
})
);
However, when all items are finished, I want to make another request. Just one.
But when I use the following code, the process stops when the first item in the from array is finished.
return this.expeditionService.getTranssmartBookingXml(request).pipe(
concatMap((response) => {
return from(response.barcodes).pipe(
concatMap((barcode) => {
return this.expeditionService.saveTranssmartBarcode({
...saveBarcodeRequest,
barcode: barcode,
});
}),
concatMap(() => {
const transsmartSaveShipmentRequest: TranssmartSaveShipmentRequest =
{
reference: this.shipmentReferenceResult!.reference,
price: this.transsmartDoBookingResponse!.price,
trackingUrl: this.transsmartDoBookingResponse!.trackingUrl,
};
return this.expeditionService.saveTranssmartShipment(
transsmartSaveShipmentRequest
);
})
);
})
I also had some slightly modified code where it was working, but then the final request was executed for each item in the array, where it only needs to execute once.
Does anybody know how to fix this? Thanks in advance!!
Piping a higher order operator like concatMap
to a stream from from
function would trigger it for each element of it's source array. You'd need to use an opeartor like last
to restrict the stream only to the last element at a specific point of the stream.
Though it wouldn't make a difference piping last
to either inner or outer observable, I'd prefer piping it to outer observable since it looks more elegant.
return this.expeditionService.getTranssmartBookingXml(request).pipe(
concatMap((response) => {
return from(response.barcodes).pipe(
concatMap((barcode) => {
return this.expeditionService.saveTranssmartBarcode({
...saveBarcodeRequest,
barcode: barcode,
});
})
)
}),
last(),
concatMap(() => {
const transsmartSaveShipmentRequest: TranssmartSaveShipmentRequest = {
reference: this.shipmentReferenceResult!.reference,
price: this.transsmartDoBookingResponse!.price,
trackingUrl: this.transsmartDoBookingResponse!.trackingUrl,
};
return this.expeditionService.saveTranssmartShipment(
transsmartSaveShipmentRequest
);
})
);