user3293692
user3293692

Reputation: 617

parameter is not of type 'Blob'

I have written the code below to display the text from a local file using the file API but when I click the button, nothing happens. I get the following error when I inspect the element in the browser. What am I doing wrong?

Uncaught TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.

<!DOCTYPE html>
    <html>
    <body>

    <p>This example uses the addEventListener() method to attach a click event to a button.</p>

    <button id="myBtn">Try it</button>
    <pre id="file"></pre>

    <script>
    document.getElementById("myBtn").addEventListener("click", function(){
       var file = "test.txt"
       var reader = new FileReader();

       document.getElementById('file').innerText = reader.result;
   
       reader.readAsText(file);

    });
    </script>

    </body>
    </html>

Upvotes: 36

Views: 155778

Answers (4)

MGLondon
MGLondon

Reputation: 1657

Well! not sure about the others, but in my case it was solved by using fileObjects[0].file

A good way to look at it would be to print your 'files' or 'fileObjects' in the console and then see whether you require the .file in the end.

Upvotes: -1

Andrew Evt
Andrew Evt

Reputation: 3689

To save the File content in innerHtml, you must first read the file. loadend event fires only when file is fully read, and you can access its content without errors:

var reader = new FileReader();
var fileToRead = document.querySelector('input').files[0];

// attach event, that will be fired, when read is end
reader.addEventListener("loadend", function() {
   // reader.result contains the contents of blob as a typed array
   // we insert content of file in DOM here
   document.getElementById('file').innerText = reader.result;
});

// start reading a loaded file
reader.readAsText(fileToRead);

You can read more here - and here

Upvotes: 15

vapcguy
vapcguy

Reputation: 7544

As the others said, I noticed that the onload event is what's missing.

So I have a couple of different ways of showing how to make the reader do something, one for doing the readAsText and one for getting the data as a base64 byte string using readAsDataURL, which is better, in my opinion, since you don't have to worry about Unicode and other weird question mark characters. To see them in action, just flip the call in the listener between uploadFile(); and uploadFile1();. And I show a couple of different ways you can grab the file object, as well:

document.getElementById("myBtn").addEventListener("click", function() {
  uploadFile1();
}); 

function uploadFile1(){
  var f = myInput.files[0];
  var reader = new FileReader();
  reader.onload = processFile(f);
  reader.readAsText(f); 
}

function uploadFile(){
  var f = document.querySelector('input').files[0];
  var reader = new FileReader();
  reader.onload = processFile(f);
  reader.readAsDataURL(f); 
}

function processFile(theFile){
  return function(e) { 
    // Use the .split I've included when calling this from uploadFile()
    var theBytes = e.target.result; //.split('base64,')[1]; 
    document.getElementById('file').innerText = theBytes;
  }
}
<input id="myInput" type="file">    
<button id="myBtn">Try it</button>
<span id="file"></span>

And normally I would think you should be able to just do:

<input type="button" onclick="uploadFile()" id="myBtn">Try it</button>

instead of having to add that listener, but it wasn't working in JSFiddle for some reason.

https://jsfiddle.net/navyjax2/heLmxegn/1/

Upvotes: 2

Quentin
Quentin

Reputation: 944568

You've made a couple of errors.

The one that the error message is complaining about is that you are trying to select a file using a hard coded string. You cannot determine which file gets loaded. The File API will only allow you to read files that are selected by the user via a File input.

The second is that you are trying to read the result property of the reader before you've read the file. You need an event handler to do that (because file reading, like Ajax, is asynchronous).

document.getElementById("myBtn").addEventListener("click", function() {

  var reader = new FileReader();
  reader.addEventListener('load', function() {
    document.getElementById('file').innerText = this.result;
  });
  reader.readAsText(document.querySelector('input').files[0]);

});
<input type="file">
<button id="myBtn">Try it</button>
<pre id="file"></pre>

Upvotes: 29

Related Questions