How can I use an uploaded file?

141 Views Asked by At

I'm trying to use "workbook" variable outside "handleFile()" function. I know I can't return the workbook variable cause it's an async function and I tried to use promises but I don't know how to do it properly. Could you help me please! Please keep in mind that I'm a newbie Thanks!

var rABS = true; // true: readAsBinaryString ; false: readAsArrayBuffer
function handleFile(e) {
  var files = e.target.files, f = files[0];
  var reader = new FileReader();
  reader.onload = function(e) {
    var data = e.target.result;
    if(!rABS) data = new Uint8Array(data);
    var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});

    /* DO SOMETHING WITH workbook HERE */
  };
  if(rABS) reader.readAsBinaryString(f); else reader.readAsArrayBuffer(f);
}
input_dom_element.addEventListener('change', handleFile, false);
3

There are 3 best solutions below

0
On

If you want to use a variable outside a function, you declare it outside the function. Make sure that the variable is either declared, or that you initialize it during the function call:

var x;
function foo() { x=5; }
function bar() { x+=10; }
foo();
bar();
console.log(x); // 15

However, I'd suggest to use classes for your case, which will allow you to link variables and functions in a more logic and easy to maintain way. Your code can be re-written as such:

class FileHandler() {

  // defines workgroup as a property
  workgroup;

  // defines a method to handle file
  handle(e) {
    // your code for handleFile(e)
    // you can access this.workgroup, even asynchronously
  }

}
0
On

The workbook variable is private so that it is secured when handling the variable.

But to answer your question, assuming you want to access it in the global scope.

replace the following line:

var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});

with

workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});

with this, you can access the workbook in the global scope with workbook or in any scope using window.workbook (assuming the window variable references to the global window object.)

0
On

If you want to use promise you will have something like this:

 function handleFile(e) {
     new Promise(function(resolve, reject) {
        var files = e.target.files, f = files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
          var data = e.target.result;
          if(!rABS) data = new Uint8Array(data);
          var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});

          /* DO SOMETHING WITH workbook HERE */
        };

        if(rABS) {
          resolve(reader.readAsBinaryString(f));
        } else {

          resolve(reader.readAsArrayBuffer(f));
        }

     });
}

Antoher example of promise(how i will do):

function handleFile(e) {
    processFile(e).then((res) => {
        // do something with reader
    });
}

function processFile(e) {
    return new Promise(function(resolve, reject) {
    var files = e.target.files, f = files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
      var data = e.target.result;
      if(!rABS) data = new Uint8Array(data);
      var workbook = XLSX.read(data, {type: rABS ? 'binary' : 'array'});

      /* DO SOMETHING WITH workbook HERE */
    };

    resolve(reader);

  });
}

input_dom_element.addEventListener('change', handleFile, false);

Hope this helps!