File API

By  on  

Working with file uploads, especially on the front end, was always a hassle.  We didn't use to be able to drag and drop files, complete AJAX uploads, provide multiple files, and hell, we couldn't get any information about the file until it hit the server; you'd need to upload the damn file before you could reject it!

Nowadays we have the File API which provides us access to file information via JavaScript and an input[type=file] element.  Let's have a look at how the File API works!

Accessing Files

To get the list of files mapped to a given input[type=file], you use the files property:

// Assuming <input type="file" id="upload" multiple>

var uploadInput = document.getElementById('upload');

uploadInput.addEventListener('change', function() {
	console.log(uploadInput.files) // File listing!
});

Unfortunately the FileList doesn't have a forEach method like Array so we'll need to do some old school looping through the FileList:

for (var i = 0, fileCount = uploadInput.files.length; i < fileCount; i++) {
  console.log(files[i]);
}

It's important to note that FileList does have a length property.

Getting File Information

Each file in the FileList provides a good set of information on each file, including file size, MIME type, last modified date, and name:

{
	lastModified: 1428005315000,
	lastModifiedDate: Thu Apr 02 2015 15:08:35 GMT-0500 (CDT),
	name: "profile.pdf",
	size: 135568,
	type: "application/pdf",
	webkitRelativePath: ""
}

What's nice about getting this file information is that you can do some very basic validation before uploading the file.  For example, you can validate MIME type or total file size:

var maxAllowedSize = 500000;

for (var i = 0, fileCount = uploadInput.files.length, totalSize = 0; i < fileCount; i++) {
	totalSize += files[i].size;
	if(totalSize > maxAllowedSize) {
		// Notify the user that their file(s) are too large
	}

	if(files[i].type != 'application/pdf') {
		// Notify of invalid file type for file in question
	}
}

Total file size is too large or a file doesn't pass the test? Now you can present the user with a message without needing to upload and assess the file first.

That's my quick look at the File API. It's a sweet little API that can save you and your user some wasted upload time. There's lots more than can be done with the file API, much of which you can find on MDN.

Recent Features

  • By
    Convert XML to JSON with JavaScript

    If you follow me on Twitter, you know that I've been working on a super top secret mobile application using Appcelerator Titanium.  The experience has been great:  using JavaScript to create easy to write, easy to test, native mobile apps has been fun.  My...

  • By
    Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

Incredible Demos

  • By
    Create an Animated Sliding Button Using MooTools

    Buttons (or links) are usually the elements on our sites that we want to draw a lot of attention to. Unfortunately many times they end up looking the most boring. You don't have to let that happen though! I recently found a...

  • By
    Elegant Overflow with CSS Ellipsis

    Overflow with text is always a big issue, especially in a programmatic environment. There's always only so much space but variable content to add into that space. I was recently working on a table for displaying user information and noticed that longer strings were...

Discussion

  1. MaxArt

    Keep in mind that the type property isn’t reliable, because browsers normally base the value solely on the file’s extension. One can rename a .php file to .pdf (for example) and it wouldn’t be noticed by the File API.

  2. Ickata
    [].slice.call(uploadInput.files).forEach(function(file, i, files) {
    	
    });
  3. Even better:

    [].forEach.call(uploadInput.files, function(file, i, files) {
    	
    });
    
  4. in ES6 :

      var uploadInput = document.getElementById('upload');
      Array.from(uploadInput).forEach(function(i) {
        ...
      });
    

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!