0

I'm working on converting an xlsx I get from a URL to a JSON object in the Browser.

This answer works --> https://stackoverflow.com/a/52237535/5079799

But, I can't get the code to wait for the reponse. All the answers online seem to be about images and/or using an input filereader, but I'm fetching a URL.

How I can wrap this all in a function that says:

  • Get XLSX from URL
  • Convert to JSON
  • Return JSON

Here is what I've been messing with so far, but it always ends with the outside variables unset but the inside works correctly.

async function Outside_Test(){
    var reso = await Get_JSON()
    console.log('reso_out')
    console.log(reso)
}

async function Get_JSON() {
    var url = "http://myspreadsheet.xlsx"
    var oReq = new XMLHttpRequest();
    oReq.open("GET", url, true);
    oReq.responseType = "arraybuffer";

    //oReq.onload = 

    return oReq.send() 
        .then(function (oReq) {
            var arraybuffer = oReq.response;

            /* convert data to binary string */
            var data = new Uint8Array(arraybuffer);
            var arr = new Array();
            for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
            var bstr = arr.join("");

            /* Call XLSX */
            var workbook = XLSX.read(bstr, {
                type: "binary"
            });

            /* DO SOMETHING WITH workbook HERE */
            var first_sheet_name = workbook.SheetNames[0];
            /* Get worksheet */
            var worksheet = workbook.Sheets[first_sheet_name];
            var reso = (XLSX.utils.sheet_to_json(worksheet, {
                raw: true
            }));
            console.log('inside-reso')
            return reso
        })

}
FreeSoftwareServers
  • 2,271
  • 1
  • 33
  • 57
  • 1
    what have you tried in `oReq.onload =` - by the way, XMLHttpRequest.send does NOT return a Promise, so not sure why you're using `.then` – Jaromanda X Nov 23 '22 at 00:57

1 Answers1

1

You'll want to return a Promise from Get_JSON that resolves when .onload is called

something like

function Get_JSON() {
    return new Promise((resolve, reject) => {
        var url = "http://myspreadsheet.xlsx"
        var oReq = new XMLHttpRequest();
        oReq.open("GET", url, true);
        oReq.responseType = "arraybuffer";
        oReq.onload = function () {
            /* convert data to binary string */
            /* Call XLSX */
            /* DO SOMETHING WITH workbook HERE */
            /* Get worksheet */
            console.log('inside-reso')
            resolve(reso);
        });
        oReq.onerror = reject;
        oReq.send() ;
    });
}

Note: no need for Get_JSON to be async ... since you never need to await

Another alternative I guess is

async function Get_JSON() {
    const arrayBuffer = await new Promise((resolve, reject) => {
        var url = "http://myspreadsheet.xlsx"
        var oReq = new XMLHttpRequest();
        oReq.open("GET", url, true);
        oReq.responseType = "arraybuffer";
        oReq.onload = () => resolve(oReq.response);
        oReq.onerror = reject;
        oReq.send();
    });
    /* convert data to binary string */
    var data = new Uint8Array(arraybuffer);
    // ...
    /* Call XLSX */
    // ...
    /* DO SOMETHING WITH workbook HERE */
    // ...
    /* Get worksheet */
    // ...
    return reso;
}

I kinda like this way, using async/await makes it clear this will return a Promise

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Thank You! I only got into JS in the last year and I've read and somewhat understand promises, but I've never had to actually write my own, I've just used functions that already have promises and just `awaited` the response. This was a good example how to write my own promise. – FreeSoftwareServers Nov 23 '22 at 19:42