backbonejs node file upload

None of the answers I have found anywhere have worked. I am trying to extend the example in "Developing Backbone.js Applications" to upload files. Although the form has enctype="multipart/form-data," request.files is always undefined.

The form HTML is:

<form id="addBook" action="..." enctype="multipart/form-data">
    <div>
        <label for="coverImage">CoverImage: </label><input id="coverImage" name="coverImage" type="file" />
        <label for="title">Title: </label><input id="title" type="text" />
        <label for="author">Author: </label><input id="author" type="text" />
        <label for="releaseDate">Release date: </label><input id="releaseDate" type="text" />
        <label for="keywords">Keywords: </label><input id="keywords" type="text" />
        <button id="add">Add</button>
  </div>
</form>

The backbone that saves the new record is

  addBook: function( e ) {
    e.preventDefault();

    var formData = {};
    var reader = new FileReader();
    $( '#addBook div' ).children( 'input' ).each( function( i, el ) {
        if( $( el ).val() != '' )
        {
            if( el.id === 'keywords' ) {
                formData[ el.id ] = [];
                _.each( $( el ).val().split( ' ' ), function( keyword ) {
                    formData[ el.id ].push({ 'keyword': keyword });
                });
            } else if( el.id === 'releaseDate' ) {
                formData[ el.id ] = $( '#releaseDate' ).datepicker( 'getDate' ).getTime();
            } else {
                formData[ el.id ] = $( el ).val();
            }
        }
    });
        console.log(formData);
        this.collection.create( formData );
    }

The Node being called.

//Insert a new book
app.post( '/api/books', function( request, response ) {
    console.log(request.body);
    console.log(request.files);
});

The value of coverimage send to node is correct, I just never get anything in request.files. I have a cool drag and drop I would like to use instead, but until I get this working I am stuck.

I tried the JQuery-file-upload, that got me nowhere.

If I had hair, I would be pulling it out right now.

I wouldn't be submitting the file as part of the model.save/collection.create(model).

What I've used is Plupload for a file upload manager, submitting a file to an upload handler. This upload handler either returns the path to the uploaded file, or fileId if a reference is stored in a database table.

From there I populate a property in my backbone model, then persist the model. You can have your model listenTo plupload, for an upload completed event or similar.

I'm also following the sample of the book "Developing Backbone.js Applications", I extended the functionality to upload images to a folder in the server and save the path in my model to show the correct images. It is working fine. I tried to use Plupload and other jquery plugins but I didn't like them. My sample is using ajax to upload images to the server and then using them. I read many posts referencing the use of iframes to have ajax functionality. The best approach for this I found is using the jquery.form.js to avoid postbacks and load the images in a nice way.

The running sample working fine with nodeJS:

https://github.com/albertomontellano/bookLibrarySampleNodeJS

I based my solution in the post of Mark Dawson:

http://markdawson.tumblr.com/post/18359176420/asynchronous-file-uploading-using-express-and-node-js

However, I had to correct a method of this post to make it work correctly:

app.post('/api/photos', function(req, res) {
var responseServerPath = 'images/' + req.files.userPhoto.name;
var serverPath = 'site/images/' + req.files.userPhoto.name;
console.log(req.files.userPhoto.path);
require('fs').rename(
    req.files.userPhoto.path,
    serverPath,
    function(error) {
        if(error) {
            console.log(error);
            res.send({
                error: 'Ah crap! Something bad happened'
            });
            return;
        }

        res.send({
            path: responseServerPath
        });
    }
);
});

I hope it helps.

Turned out I had to end up hiring someone to do it, because I can't find any examples online of anybody uploading a file through backbone, even without updating any database interaction. Everybody has the same basic advice about what tools to use to upload the files, but I can't for the life of me find ONE example of someone implementing it.

I am planning on making the code available to everybody, so they can see how it works.