1

I have code that does POST attachments to Couch docs using jquery.form.js. That's all good, but I really need to allow the user to enter multiple files in the form, let's say 5 files for now, then in code iterate the five files in the form, creating one new Couch doc and attachment for each file. This is veeeery difficult if not impossible using only jQuery. It could be done using Couch "inline attachments" but then you would need a server-side (PHP probably) script to Base64 encode the binary image data. This really isn't an option for me because this is a Couchapp.

So the following code doesn't work, it generates an "invocation" error in jQuery. My assumption is that you can't simply add the reference to a binary file in the data attrib...

    var url= _.couchUrl() + me.photoArgs.db +"/" + 
             couchDoc._id + "/attachment?rev=" + couchDoc._rev;
    $.ajax({
        type: "PUT",
        url: url,
        headers: { 
            "Content-Length": file.size,
            "Content-Type": file.type 
        },
        data: file,
        success: function (response) {
            console.log("Attachment was uploaded");
            me.fileCnt--;
            if (me.fileCnt == 0) console.log("Attachment(s) uploaded");
        },
        error: function (response) {
            _.flashError('Attachment ajaxSubmit failed',me,response);
        }
    });

The code is clipped from inside a larger function. I've logged the url and the file, they both have correct data so they're not the issue.

Does anyone think the above should work? If so, what am I doing wrong?

Thanks a lot for your advice :-)

Locohost
  • 1,682
  • 5
  • 25
  • 38

1 Answers1

0

You have two options there:

  1. Use inline attachments. You don't have to use PHP to decode base64 data: just add to your CouchApp /_utils/script/base64.js file (yes, it ships with CouchDB Futon) as CommonJS module and you'll be fine.

  2. Use Multipart API (scroll a bit down for an example). I haven't much experience with jQuery to quick make a working prototype, but this question you may found helpful.

Update: found good working example how to upload multiple binary attachments to CouchDB using multipart API.

Community
  • 1
  • 1
Kxepal
  • 4,659
  • 1
  • 19
  • 16
  • Thanks for the reply. I looked at the base64.js in Couch but that doesn't do what you think. It encodes/decodes *strings* in base64 not binary image data. Your (2) example also relies on a binary image blob encoded as base64. – Locohost Oct 26 '13 at 20:52
  • @Locohost aha, thanks for notes. I wonder how PouchDB solves such problem since it should be common for it. – Kxepal Oct 26 '13 at 22:59
  • If I moved the app out of Couch (Couchapp) and back into a normal web app, I could use a very simple PHP script to base64 the binary image data. – Locohost Oct 27 '13 at 01:47
  • @Locohost I'd updated the post with new example I found: using multipart api it uploads multiple attachments to CouchDB and looks like no base64 stuff - all images stores like they should. – Kxepal Oct 27 '13 at 13:55
  • I did see that multi-part example and read through it. The problem is that will probably work fine using Curl to do the PUT because Curl will Base64 the image blob before PUT'ing. jQuery ajax PUT doesn't do that. – Locohost Oct 27 '13 at 19:09
  • Looking again, it says it doesn't need the image Base64 encoded. That' fine and that should work fine with Curl, but it still won't happen in a jQuery ajax PUT. The only way I see to send image binary data is throught POSTing. – Locohost Oct 27 '13 at 19:12
  • @Locohost sorry, my update contained wrong link! Have fixed it now. – Kxepal Oct 27 '13 at 19:42
  • Looks like we're Googling and finding the exact same articles ;-) My current file upload jQuery code is based on rjsteinert's example. I've modified it greatly, but RJ's example was my seed. RJ's code displays a form that allows you to select multiple files and then uploads them all to a single Couch doc. It definitely works, I've used it. But my requirement is different. I need to upload multiple files to multiple Couch docs. Each file attaches to it's own doc. This will not happen as PUTs from jQuery, only POSTs. I actually have figured out a workaround and I'll post it here later today. – Locohost Oct 28 '13 at 14:55
  • Heh (: however, `I need to upload multiple files to multiple Couch docs` statement makes a sense since you cannot do this with PUT requests and Bulk API doesn't support multipart requests. So you have only to use RJ's example within some loop over all your docs or serialize files with base64 and use `_bulk_docs` endpoint. – Kxepal Oct 28 '13 at 15:02