The requirement:
- The user selects multiple invoices from Angular table and clicks on download
- In a for loop the getClient method is executed to get client detail from server for each invoice
- Within the 'subscribe' of the getClient method, another method (serviceLogService.downloadInvoicePdf) is executed to download the invoice in PDF form.
Problem: When multiple invoices are selected, lets say 3 invoices, all the three invoices get downloaded - BUT all of them have the details of the last chosen invoice.
As I understand this is due to the async call of this.clientsService.getClient() getting executed one after another(in for loop) without waiting to execute the code within subscribe.
What would be the best way to handle this so that the required execution flow is completed before executing the next loop? Pls see at the bottom what I tried.
component.ts
onDownload(){
if(this.selection?.selected.length <= 0) return;
const selectedInvoices = this.selection?.selected;
for(const invoice of selectedInvoices) {
this.clientsService.getClient(invoice.compId)
.subscribe(client => {
if(client) {
this.serviceLogService.downloadInvoicePdf(this.cust, client, invoice);
}
});
}
}
clientsService
getClient(id: string) {
return this.httpClient.get<Client>(this.reqUrl + '/' + id);
}
serviceLog-service
downloadInvoicePdf(cust: Cust, client: Client, invoice: Invoice) {
const invoiceName = client.compName + ' Inv-' + invoice.invNumber
const isTaxInvoice = false;
this.pdfService.generateDownloadInvPdf(cust, client, invoice, invoiceName, isTaxInvoice);
}
pdfService
async generateDownloadInvPdf(cust: Cust, client: Client, invoice: Invoice, fileName: string, isTaxInvoice: boolean) {
await this.prepareInvoicePdf(cust, client, invoice, isTaxInvoice);
await this.loadPdfMaker();
this.pdfMake.createPdf(this.docDef).download(fileName);
}
async prepareInvoicePdf(cust: Cust, client: Client, invoice: Invoice, isTaxInvoice: boolean) {
// ...code...
this.docDef = {
// ... code
}
}
async loadPdfMaker() {
if(!this.pdfMake) {
const pdfMakeModule = await import('pdfmake/build/pdfmake');
const pdfFontsModule = await import('pdfmake/build/vfs_fonts');
this.pdfMake = pdfMakeModule.default;
this.pdfMake.vfs = pdfFontsModule.default.pdfMake.vfs;
}
}
Tried below async await but could not proceed due to the type error:
async onDownload(){
if(this.selection?.selected.length <= 0) return;
const selectedInvoices = this.selection?.selected;
for(const invoice of selectedInvoices) {
const client = await this.clientsService.getClient(invoice.compId);
if(client) {
this.serviceLogService.downloadInvoicePdf(this.cust, client, invoice);
// VSC error for arg client:
// Argument of type observable<Client> is not assignable to parameter of type 'Client'
}
}
}