11

I need some help returning the "bytes" variable from this function below to be used as input in another function.

function openfile() {
var input = document.getElementById("files").files;
var fileData = new Blob([input[0]]);

var reader = new FileReader();
reader.readAsArrayBuffer(fileData);
reader.onload = function(){
    var arrayBuffer = reader.result
    var bytes = new Uint8Array(arrayBuffer);
    console.log(bytes);
}

I'd like to get the return of the above function and use the array of bytes as input parameter in another function.

2
  • How about return bytes;? To use it as a parameter for another function, use it like this: myfunction(openfile(evt)); Commented Jul 15, 2015 at 14:46
  • I get "undefined" if changing from "console.log(bytes);" to "return bytes;" and calling outside "console.log(openfile());" Commented Jul 15, 2015 at 15:33

2 Answers 2

20

You can use promises to wait for the file reader to finish loading your file.

The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected to in the future.

Here you can find more information on promises.

Here is an example on how you could integrate a promise into your situation.

(function (document) {
  var input = document.getElementById("files"),
      output = document.getElementById('output');

  // Eventhandler for file input. 
  function openfile(evt) {
    var files = input.files;
    // Pass the file to the blob, not the input[0].
    fileData = new Blob([files[0]]);
    // Pass getBuffer to promise.
    var promise = new Promise(getBuffer(fileData));
    // Wait for promise to be resolved, or log error.
    promise.then(function(data) {
      // Here you can pass the bytes to another function.
      output.innerHTML = data.toString();
      console.log(data);
    }).catch(function(err) {
      console.log('Error: ',err);
    });
  }

  /* 
    Create a function which will be passed to the promise
    and resolve it when FileReader has finished loading the file.
  */
  function getBuffer(fileData) {
  	return function(resolve) {
        var reader = new FileReader();
        reader.readAsArrayBuffer(fileData);
        reader.onload = function() {
          var arrayBuffer = reader.result
          var bytes = new Uint8Array(arrayBuffer);
          resolve(bytes);
        }
    }
  }
  
    // Eventlistener for file input.
  input.addEventListener('change', openfile, false);
}(document));
<input type="file" id="files" />
<div id="output"></div>

Sign up to request clarification or add additional context in comments.

5 Comments

Not quite what I was looking for. But I think I'll change the way I was planning to do this. Thank you.
Note that IE didn't support Promise objects until version 11.
Look nice but does not work for me. Line var bytes = new Uint8Array(arrayBuffer); has an error TS2345: Argument of type 'string | ArrayBuffer' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer | ArrayLike<number>'.
@mli Hi, may I ask, are you using TypeScript? If so, are you sure that you are correctly casting your types?
@DavidDomain. Yea, it's typescript. So I was forced to put it like this: const bytes = new Uint8Array(reader.result as ArrayBuffer); Thanks anyway, I'm just newbie, so I thought there is no difference between javascript and typescript.
4

If you pass the onload function the event, you can make it work.

reader.onload = function(e){
    var arrayBuffer = e.target.result;
    var bytes = new Uint8Array(arrayBuffer);
    console.log(bytes);
}

This corrects it from reader.result to e.target.result;.

Additionally, there's a problem in using fileData, which is set to Blob[files[0]] and sending that to reader.readAsArrayBuffer. Remove fileData and call it with reader.readAsArrayBuffer(input[0]);, instead.

2 Comments

e.target has no result property.
@KingWilder If you're using IE, you might need e.srcElement instead. It's there if you're using Chrome. But also something that was likely making it not work, the OP is basically using reader.readAsArrayBuffer(new Blob([input[0]])); when it should've been reader.readAsArrayBuffer(document.getElementById("files").files[0]);, which didn't originally get addressed, here, and will alter what e is. I added it in an edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.