Simple AJAX image upload with Rails


I was developing a small feature: AJAX upload user avatars. This means:

  • User select an image from local computer
  • Avatar is uploaded immediately after being selected
  • Update user avatar display after uploading successfully

All without reloading the page.

There are plenty of JS libraries that satifies the requirements above however after trying several libraries, I decided to not use any of them for the following reasons:

  • adding a library is too much, the library often offers too many configs and options that almost unnecessary for this case.
  • libraries often hack the element and inject their own style. making their style fit with provided design is often too complex to make it worth.

Therefore I'm searching for a minimalistic solution and came up with the piece of code below:

$(document).on('turbolinks:load', function() {
  $("#js-avatar-uploader").change(function() {
    var fd = new FormData();
    fd.append('avatar', $('#js-avatar-uploader')[0].files[0])

    $.ajax({
      url: '/avatars',
      data: fd,
      processData: false,
      type: 'POST',
      contentType: false,
      cache: false,
      mimeType: 'multipart/form-data',
      dataType: 'JSON',
      beforeSend: function() {
        $('span.js-upload-text').text('Uploading...')
      }
    })
    .done(function (data) {
      $('img#js-avatar').attr('src', data.avatar)
    })
    .always(function () {
      $('span.js-upload-text').text('Upload New Image')
    })
  })
})

This solution ultilizes FormData interface (https://developer.mozilla.org/en-US/docs/Web/API/FormData) and jQuery AJAX.

To make the AJAX call work with file uploading, the following options must be set as follow:

processData: false,
contentType: false,
cache: false,
mimeType: 'multipart/form-data',