How filepicker saved us a lot of trouble


Adding upload possibilities to an application is often not a pleasant experience. How often did you forget to configure the upload size? Or forgot to whitelist the mimetypes? And that is just the basic implementation. What if you need to support mobile browsers, how is one going to upload a document from his iPhone?

At Qandidate.com we had to implement file uploads as well. Besides the regular upload it should also support selecting files from cloud services like Google Drive and Dropbox. Instead of trying to implement all integrations ourselfs we decided to look for services that could handle this for us. We found filepicker, a service that supports 22 sources out of the box. Besides selecting files from your computer you can also select files from Dropbox, Google Drive, Facebook, SkyDrive or even from FTP.

First step

After creating an account you will need to create your first application. You will receive the API key to use.

Now we can actually get started implementing it in a website.

<script type="text/javascript" src="//api.filepicker.io/v1/filepicker.js"></script>

By adding that script you are all set. If you prefer a non-blocking script, they support that as well.

The quickest way to get a working prototype is to use the widget Filepicker provides:

<input type="filepicker" name="myFile" data-fp-apikey="<yourApiKey>" />

This will allow the user to upload a file. If you submit your form, it will POST the url of the Filepicker URL, instead of uploading the body.

Using the Javascript API

The widget is a great first step to get to know Filepicker. To have more control over Filepicker and the uploads you can use the Javascript API. With the API you can also set the API key globally, so you don't have to set it on each widget you define.

filepicker.setKey('<yourApiKey>');

One possibility is to let a user select only images and display a preview after uploading the image.

jQuery('.filepicker').on('click', function() {
  var button = this;
  filepicker.pick(
    { mimetypes: ['image/*'] },
    function(File) {
      var image = $('<img />').attr('src', File.url);
      jQuery(button).before(image);
    }
  );
});
<button class="btn filepicker">Choose an image</button>

An example of the File argument that you will receive in the success callback:

{
  "mimetype" : "image/jpeg",
  "url" : "https://www.filepicker.io/api/file/fPKsueFCQ3qSEoQBDhe",
  "isWriteable" : true,
  "filename" : "avatar.jpg",
  "size" : 38106,
  "container" : "qandidate",
  "key" : "551Cf5Fa40D4d_avatar.jpg"
}

But... where are my files?

When a user uploads a file from his computer, filepicker stores it on their own servers. But when a user selects a file from one of the other providers, filepicker will only store a reference to the file. This means, that if a user chooses a file from his Google Drive and later deletes it from his Drive, you won't have access to that file anymore.

Filepicker provides a solution for that on their paid plans. You can then configure one or more cloud services where you can store files. At this moment they have support for Amazon S3, Azure, Rackspace and Dropbox.

To let Filepicker directly store your uploads on a cloud service you configured, you should use pickAndStore instead of pick. With that method, you can configure how and where the file should be stored. You can also configure if it should be stored publicly or privately.

var pickOptions = { multiple: false };
var storageOptions = {
  location: 'S3',
  path: '/labs.qandidate.com/pickAndStore',
  container: 'qandidate',
  access: 'public'
};
filepicker.pickAndStore(pickOptions, storageOptions, function(Blobs) {});

Note that you get an array with Files, even when you configured it with multiple: false.

But that's not all!

Filepicker offers many more features, one of which: converting just uploaded images.

For example, you can easily create a cropped thumbnail of an avatar, while keeping the face in the center. Pass filepicker.convert a blob from a just uploaded file and provide the parameters for the conversion.

filepicker.pick(
  { mimetypes: ['image/*'] },
  function(file) {
    var conversionOptions = {
      width: 100,
      height: 150,
      fit: 'crop',
      align: 'faces'
    };
    filepicker.convert(file, conversionOptions, null, function(convertedFile) {});
  }
);

To keep in mind

Filepicker gives us a lot of benefits and saves us the hassle of building and maintaining the features they provide ourselves. We decided on using it, because it allowed us to have features from our roadmap for which we otherwise might never have found the time to build. But it also comes with a pricetag, Filepicker isn't cheap with large volumes, so that is something that you have to take into account.

Have fun exploring Filepicker!