Home > Back-end >  Wait for function to finish reading excel file
Wait for function to finish reading excel file

Time:04-19

I want to read an excel file and return the data in json format. When I call 'readExcelSheet' function on button click, it returns 'undefined' as function hasn't been finished reading the excel data. On subsequent click, data does return properly. I want to wait for this function until it read complete data.

constructor(private httpClient: HttpClient) {
    }

readExcelSheet() {
    let dataJson;
        this.httpClient.get(this.filePath, { responseType: 'blob' })
            .subscribe((data: any) => {
                const reader: FileReader = new FileReader();

                reader.onload = (e: any) => {
                    //   reader.readAsBinaryString(e.target.files[0]);
                    const bstr: string = e.target.result;
                    const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });

                    /* grab first sheet */
                    const wsname1: string = wb.SheetNames[0];
                    const ws1: XLSX.WorkSheet = wb.Sheets[wsname1];

                    dataJson = XLSX.utils.sheet_to_json(ws1);
                };
                reader.readAsBinaryString(data);
            });

        return dataJson;
    }

CodePudding user response:

When you call subscribe, the code executes this line asynchronously (ie: skips over this line and go to the return immediately). Use lastValueFrom in an async-await function instead.

Try doing this:

async readExcelSheet(){
 let dataJson;
 const data = await lastValueFrom(this.httpClient.get(this.filePath, { responseType: 'blob' }))
 const reader: FileReader = new FileReader();

 reader.onload = (e: any) => {
  const bstr: string = e.target.result;
  const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });

  /* grab first sheet */
  const wsname1: string = wb.SheetNames[0];
  const ws1: XLSX.WorkSheet = wb.Sheets[wsname1];

  dataJson = XLSX.utils.sheet_to_json(ws1);
 };
 reader.readAsBinaryString(data);
 return dataJson;
}

CodePudding user response:

Try using ASYNC & AWAIT in your functions

async readExcelSheet()

CodePudding user response:

Try to use toPromise instead of subscribe and then you can return the function. You can then try to use Promise.resolve() to resolve the dataJson.

constructor(private httpClient: HttpClient) {
}

readExcelSheet() {
  return this.httpClient.get(this.filePath, { responseType: 'blob' })
        .toPromise().then((data: any) => {
            const reader: FileReader = new FileReader();

            reader.onload = (e: any) => {
                //   reader.readAsBinaryString(e.target.files[0]);
                const bstr: string = e.target.result;
                const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });

                /* grab first sheet */
                const wsname1: string = wb.SheetNames[0];
                const ws1: XLSX.WorkSheet = wb.Sheets[wsname1];

                Promise.resolve(XLSX.utils.sheet_to_json(ws1))
            };
            reader.readAsBinaryString(data);
        });

}
  • Related