Working with the File API

April 14th, 2014

For an app I am working on I wanted to upload an image through javascript and save it as a dataURL and then send it away to my MongoDB. At first I thought I would just get the image from an <input type='file'> and put it on a canvas and then get the information from there, but of course I ran into some issues, as just using the <input type='file'> will not give you what you want.

In comes the File API. This is fairly straight forward but it was hard to wrap my head around at first. Using the File API you create a new File object and then pass that into a Filereader object. From there you are able to read your file!

Here is a working example:

See the Pen Working with the File API by Ryan Christiani (@Rchristiani) on CodePen.

But lets walk through this a bit:


$(function() {
  var $fileInput = $('input[type=file]');
  var $imageArea = $('img');
  var fileInfo;

  $fileInput.on('change', getFileInfo);

  function getFileInfo(e) {
    var file = e.target.files[0];
    var reader = new FileReader();

    reader.onload = (function(imageFile) {
      return function(e) {
         fileInfo = e.target.result;
         $imageArea.attr('src',fileInfo);
      }
    })(file);
    reader.readAsDataURL(file);
  }
});

The first few lines are pretty simple. We get some information from the DOM, we get the input[type=file] and then get our blank img element.

We set up an event to be fired on the change event. In here is where all the magic happens. We first gather some data from the event and save it to a variable called file we do this using e.target.files[0] were files is a FileList, which is just an array. Since we are just uploading one image we will just get the first element from that array.

We then create a new FileReader, and here is where I had a little issue trying to figure this out. But there is a great post on HTML5 Rocks about this that explains:

“When the load finishes, the reader’s onload event is fired and its result attribute can be used to access the file data.”

http://www.html5rocks.com/en/tutorials/file/dndfiles/

So the pattern used here is to create an immediately invoked function expression that takes an argument, in this case the file, and returns a function that takes the event data from the onload event. The result of this is our DataURL image!

The other key step here is the readAsDataURL() method which is used to tell the FileReader how we want our data.

Play around with the Codepen on the page to see it in action, and hopefully this helps you out!