0
votes

I am trying to PUT my data within its attachment. I am doing it with NodeJS

Here is my code:

var date = new Date();

var data = {
  name : obj.name,
  serving : obj.serving,
  cuisine : obj.cuisine,
  uploadDate : date,
  ingredients : obj.ing,
  directions: obj.direction
}   //Assume that I read this from html form and it is OK

db.insert(data, function(err, body){
  if(!err){
    console.log(body);
    var id = body.id
    var rev = body.rev

    var headers = {
      'Content-Type': req.files.image.type
    };

    var dataString = '@' + req.files.image.path;

    var options = {
      url: 'https://username:[email protected]/db_name/' + id + '/' + req.files.image.name +'?' + 'rev=' + rev,
      method: 'PUT',
      headers : headers,
      body : dataString
    }

    console.log(options)

    function callback(error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log(body);
      }
    }
    request(options, callback);

  }

});

I am getting a 201 response after an image attachment has been sent. But in the cloudant dashboard I see "length": 38 of uploaded image which is impossible.

If I try to access uploaded image it gives:

{"error":"not_found","reason":"Document is missing attachment"}.

How I can fix this problem?

1

1 Answers

2
votes

It looks like you are uploading the path to the image and not the contents of the image itself:

var dataString = '@' + req.files.image.path;

This will just upload the string '@xyz' where xyz is the path of the file. You need to upload the contents of the image. See the following for more information:

https://wiki.apache.org/couchdb/HTTP_Document_API#Attachments

I am not sure how to get the contents of the uploaded file from req.files. I believe req.files no longer works in Express 4, so I use multer:

https://github.com/expressjs/multer

This is how I upload a file to Cloudant that was uploaded to my app:

Client

<form action="/processform" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile">
    <input type="submit" value="Submit">
</form>

Node.js Routing

var multer  = require('multer');
...

var app = express();
...

var uploadStorage = multer.memoryStorage();
var upload = multer({storage: uploadStorage})
app.post('/processform', upload.single('myfile'), processForm);

Note: 'myfile' is the name of the file input type in the form.

Node.js Upload to Cloudant

function processForm() {

    // insert the document first...

    var url = cloudantService.config.url;
    url += "/mydatabase/" + doc.id;
    url += "/" + encodeURIComponent(req.file.originalname);
    url += "?rev=" + doc.rev;

    var headers = {
        'Content-Type': req.file.mimetype,
        'Content-Length': req.file.size
    };

    var requestOptions = {
        url: url,
        headers: headers,
        body: req.file.buffer
    };

    request.put(requestOptions, function(err, response, body) {
        if (err) {
            // handle error
        }
        else {
            // success
        }
    });

    ...
}