Inside a method (code below) I am trying to set an array of strings called 'outerURL' in the promise. and when the promise is resolved, I am pushing the values of 'outerURL' to an array called 'tableValues' to be displayed in a .pdf.
When I try to download the .pdf file in the first attempt after the page loads, I get 'undefined' in the place where the content of 'outerURL' should be displayed. When I try to download the .pdf file the second time, I can see the 'outerURL' content are being displayed.
In the first attempt to download the .pdf it seems the method is returning 'filePrintList' before the promise completes and by the second time I download the .pdf, the promise is already completed and 'outerURL' values are set.
My question is, how can I wait for the promise to finish before returning 'filePrintList'?
Below is my code:
let promise = new Promise((resolved, rejected) => {
this.fileDetails.forEach(async file => {
const rowValue: any = [];
this.coreService.viewFileNew(file, false).subscribe(
fileData => {
this.showProgress(false);
if (fileData.size > 0) {
const url = URL.createObjectURL(fileData);
this.outerURL.push(url);
} else {
file.isActive = false;
}
},
err => {
console.log(err);
}
);
});
resolved(this.outerURL);
});
promise.then(urls => {
urls.forEach(url => {
rowValue[this.FILE_PRINT_TABLE_COLUMN_NAME] = value;
rowValues.push(rowValue);
tableValues.push(url);
});
});
fileTableList.rowDataList = rowValues;
fileTableList.tableListData = tableValues;
fileTableHeaderList.push(fileTableList);
fileTable.tableList = fileTableHeaderList;
fileTables.push(fileTable);
filePrintList.tableList = fileTables;
return filePrintList;
How about if you send the file array to the service, and then it will return to the component an array of observables
service.ts
...
export class CoreService {
viewFileNew(files: any[], flag: boolean): Observable<any>[] {
const result$: Observable<any>[] = [];
for (let i = 0; i < files.length; i++) {
// I guess the service function is doing something similar
result$.push(this.http.get(.../files[i]));
}
return result$;
}
}
component.ts
yourFunction() {
this.showProgress(false);
const rowValue: any = [];
const array$ = this.coreService.viewFileNew(this.fileDetails, false);
...
...
array$.forEach((data$, index) => data$.subscribe((data) => {
if (data.size > 0) {
const url = URL.createObjectURL(data);
rowValue[this.FILE_PRINT_TABLE_COLUMN_NAME] = value;
rowValues.push(rowValue);
tableValues.push(url);
if (index === array$.length - 1) {
fileTableList.rowDataList = rowValues;
fileTableList.tableListData = tableValues;
fileTableHeaderList.push(fileTableList);
fileTable.tableList = fileTableHeaderList;
fileTables.push(fileTable);
filePrintList.tableList = fileTables;
// probably it will be useful to have some sort of a subject
// so you can next the final result
// probably there is a simpler approach, hope this helps a bit
this._subject.next(filePrintList);
}
} else this.fileDetails[index].isActive = false;
}))
}