David Jones
David Jones

Reputation: 10219

Forcing Backbone to save an attribute as a file

Is there a way to use Model.set and Model.save in a way that will force Backbone to send the data to the server as a file (as if you were submitting a form with an <input type="file"> tag?

Upvotes: 3

Views: 1223

Answers (1)

Andrew Hubbs
Andrew Hubbs

Reputation: 9436

The short answer is no. The long answer is, sort of.

This doesn't really have anything to do with Backbone and instead is about being able to AJAX a file in the browser. The solution is to use the File API from HTML 5. Below is an example of how you would do that with a Backbone model.

Let's assume we have a User model and we want to save an avatar file on that model.

// Backbone Model JS

User = Backbone.Model.extend({
  readAvatar : function (file, callback) {
    var reader = new FileReader(); // File API object for reading a file locally
    reader.onload = (function (theFile, self) {
      return function (e) {
        // Set the file data correctly on the Backbone model
        self.set({avatar_file_name : theFile.name, avatar_data : fileEvent.target.result});
        // Handle anything else you want to do after parsing the file and setting up the model.
        callback();
     };
    })(file, this);
    reader.readAsDataURL(file); // Reads file into memory Base64 encoded
  }
});

// Somewhere in your view JS

this.$("input[type='file']").change(function (event) {
  var file = e.originalEvent.target.files[0];
  userModel.readAvatar(file, userModel.save);
});

// HTML
<form><input type="file" name="avatar"/></form>

Now on your back end you need to handle the file coming through as Base64 encoded data.

A couple of warnings:

  1. If you need extensive browser support then this solution probably won't work for you.

  2. Base64 encoding a file is going to increase the amount of data sent over the wire by about 30%.

Upvotes: 6

Related Questions