Reputation: 246
I tried to do following function with concat map. but i'm not sure what is the correct way for that.
//Req 01
await this.shippingInfoService.getShipmentInfoByCardId(this.data.CardId).then(async (shipmentData) => {
if (shipmentData != undefined) {
if (shipmentData.ShipmentId !== null && shipmentData.ShipmentId !== "") {
//If shipment is assigned
let shipmentId = shipmentData.ShipmentId;
let contract = JSON.parse(sessionStorage.getItem(SITE_DETAILS_KEY)).Contract;
let printObj = {
"ShipmentId": Number(shipmentId),
"Contract": contract
}
//Second Req
await this.orderDetailsService.printBillOfLading(printObj).then(async () => {
await this.orderDetailsService.getBillOfLeadingPdfInfo(shipmentId).then(async (response) => {
if (response.ResultKey === null || response.Id === null) {
const dialogConfig = new MatDialogConfig();
dialogConfig.data = "The information needed to generate a report isn't available.";
dialogConfig.disableClose = true;
this.dialog.open(ErrorDialogComponent, dialogConfig);
//Hide Loading indicator
this.store.dispatch(setLoadingSpinner({showLoading: false}));
} else {
// 3rd Req
let url = await this.orderDetailsService.generateBillOfLadingPdfUrl(response.ResultKey, response.Id);
await window.open(url.url, "_blank");
//Hide Loading indicator
await this.store.dispatch(setLoadingSpinner({showLoading: false}));
}
});
});
} else {
//If shipment is not assigned
//Hide Loading indicator
this.store.dispatch(setLoadingSpinner({showLoading: false}));
//Error
const dialogConfig = new MatDialogConfig();
dialogConfig.data = "Shipment needs to be connected";
dialogConfig.disableClose = true;
this.dialog.open(ErrorDialogComponent, dialogConfig);
}
}
})
Need to refactor above code with rxjs operators.
Upvotes: 0
Views: 180
Reputation: 14679
getShipmentInfo().pipe(
map(response => parseShipmentData(response)),
switchMap(printObj => forkJoin([
// Why do them in sequence? You aren't using results from `printBillOfLading` for anything
printInvoice(printObj),
getPdfInfo(printObj.ShipmentId),
]),
switchMap(([nevermind, pdfResponse]) => handlePdfResponse(pdfResponse))
)
with parseShipmentData
, printInvoice
, getPdfInfo
and handlePdfResponse
filled with the relevant pieces of logic from your original code. BTW mixing await
with then
and nesting async
functions is unnecessary and only obfuscates your code.
Upvotes: 0
Reputation: 8022
This is a refactoring of your code, altering as little as possible (to a point). I don't think this is the most idiomatic way to write RxJS, but then I also wouldn't write Promises as above either.
I can't test any of this, so this is the shape of an answer, and not an answer unto itself. Maybe it'll get you started...
Best of luck:
//Req 01
from(this.shippingInfoService.getShipmentInfoByCardId(this.data.CardId)).pipe(
filter(shipmentData => shipmentData != undefined),
tap(shipmentData => {
if (shipmentData.ShipmentId !== null && shipmentData.ShipmentId !== "") {
throw "Shipment needs to be connected"
}
}),
// Second Req because shipment is assigned
concatMap(shipmentData => this.orderDetailsService.printBillOfLading({
"ShipmentId": Number(shipmentData.ShipmentId),
"Contract": JSON.parse(sessionStorage.getItem(SITE_DETAILS_KEY)).Contract
}).pipe(
map(_ => Number(shipmentData.ShipmentId))
)
),
concatMap(id => this.orderDetailsService.getBillOfLeadingPdfInfo(id)),
tap(response => {
if ( response.ResultKey === null || response.Id === null) {
throw "The information needed to generate a report isn't available."
}
}),
// 3rd Req
concatMap(response =>
this.orderDetailsService.generateBillOfLadingPdfUrl(response.ResultKey, response.Id)
),
// Catch errors thrown above
catchError(error => {
// This isn't really comprehensive error management for obvious reasons.
// I'm assuming the only errors are one of the two strings thrown above.
const dialogConfig = new MatDialogConfig();
dialogConfig.data = error;
dialogConfig.disableClose = true;
this.dialog.open(ErrorDialogComponent, dialogConfig);
// Returning empty means we don't propogate this error
return EMPTY;
}),
// Always finish by Hiding Loading indicator
finalize(() => this.store.dispatch(setLoadingSpinner({showLoading: false})))
).subscribe(
url => window.open(url.url, "_blank")
);
Upvotes: 1