0

I am using an XMLHttpRequest and sheetjs (https://github.com/SheetJS/js-xlsx) to create a json object from an excel spreadsheet. All is working well except I am struggling to access the created object outside of oReq.onload. After creating the json object I would like to use it as the input object to more code below the XMLHttpRequest.

I have tried to return json at the end of oReq.onload and also tried include my additional code inside function (e) {} but neither option has worked. Any suggestions would be appreciated.

    /* set up XMLHttpRequest */
    var url = "graph.xlsx";
    var oReq = new XMLHttpRequest();
    oReq.open("GET", url, true);
    oReq.responseType = "arraybuffer";

    oReq.onload = function(e) {
      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"});

      /* Create the json object */
      var json = to_json(workbook); 

      /*Converts excel format to JSON*/
      function to_json(workbook) {
        var result = {};
        workbook.SheetNames.forEach(function(sheetName) {
            var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
            if(roa.length > 0){
                result[sheetName] = roa;
            }
        });
        return result;
      }
    };
    oReq.send();

    /*I WOULD LIKE TO USE THE CREATED JSON OBJECT HERE*/
linesd
  • 31
  • 9
  • Well you can not use it after since it is asynchronous. Make a method that has the logic you want to run and pass the JSON to that method. See http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron – epascarello Aug 09 '16 at 12:46
  • Excellent, thanks very much that has done the trick! If you put that as the answer I'll accept it. – linesd Aug 09 '16 at 13:16

3 Answers3

0

Ended up being an asynchronous problem as suggested by @epascarello. A very comprehensive explanation can be found in the post: Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

Community
  • 1
  • 1
linesd
  • 31
  • 9
0

using callback you can get the data outside the function, as is explained here https://stackoverflow.com/a/23667087/7981344

function asyncReq(callback){ 
oReq.onload = function(e) {

  var arraybuffer = oReq.response;

  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("");

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

  var sheet_name = workbook.SheetNames[0];
  var worksheet = workbook.Sheets[sheet_name];
  myJson = XLSX.utils.sheet_to_json(worksheet, {
    header: 1
  });
callback(myJson);
}
}

oReq.send();
asyncReq(function(result){
   //do whatever you want now with the output data
console.log(result);
Community
  • 1
  • 1
EdSilva
  • 25
  • 1
  • 6
-1

hope this is not too late, but i came across the same problem. just set a timeout, and wait for the onload function to finish like this

setTimeout(function() {
  console.log (yourvariable); //prints the variable outside the function
}, 1000);
EdSilva
  • 25
  • 1
  • 6
  • 1
    How do you know that waiting 1000ms is long enough? What if the request takes 2 seconds? What if it takes 5 seconds? This is **NEVER** the way to handle asynchronous code. – gforce301 May 10 '17 at 16:21
  • i realize is not the good way to deal with asynchronous code, maybe using callback function? but i dont know how it's works yet – EdSilva May 10 '17 at 17:00
  • I can appreciate that you don't know yet how to do it properly. If you realize this, why would you give an answer that you know is not correct? And yes, using a callback function is the correct way to handle this. – gforce301 May 10 '17 at 17:03