8

I am trying to POST an image from my Node JS app to another REST API. I have the image in Mongo DB (as binary array data) that is read by Node JS and then is supposed to be POSTed to another API.

The problem I face is how do I send request data along with the image? I have this raw data (that is in JSON format) that should be POSTed along with image:

{"data":{"client":"abc","address": "123"},"meta":{"owner": "yourself","host": "hostishere"}}

I am required to do this using the 'request' module. I can use 'multer' if that helps better. But, I am stuck on how do I send the above request data along with the image stream. Below is my current code. Could you please help me finish it?

        var options = {
            host: 'hostname.com',
            port: 80,
            path: '/api/content',
            method: 'POST',
            headers:{
                'Content-Type' : 'multipart/form-data'
            }
        };

        var request =  http.request(options, function(response) {
            var str = '';
            var respTime ='';

            response.on('data', function (chunk) {
                str = str.concat(chunk);
            });
            response.on('end', () => {
                console.log('No more data in response.');
            });

            setTimeout(function() {
                res.send(JSON.stringify(
                  {
                      'imageURL': IMG_URL,
                      'imageId': IMG_ID,
                      'body': JSON.parse(str)
                  }
                ));
            }, 1000);
        });

        request.on('error', (e) => {
          console.error('**** problem with request: ', e);
        });

        request.write(image.IMG_STR); //image.IMG_STR is the binary array representation of the image.
        request.end();

UPDATE: 06/06/2017

So, I happened to talk to the REST team that provides the end point and found out that the data should be sent in the following specific format. Below is a snapshot of the request that succeeded. Could someone help me with the Node code that I should use? I have tried form-data package but have been getting the same error: Postman Snapshot

rajugaadu
  • 686
  • 2
  • 17
  • 37
  • 1
    Why the timeout? You should send your response in the `end` event listener. If your request takes longer than 1 second the response won't be complete – Jonas Zell Jun 01 '17 at 08:25
  • @JonasZell thank you for pointing out the correct usage of request.end() and why setTimeout should be avoided. Will make the changes to improve this piece of code. Coming to your other question, 'res' is actually the response object for the request which invokes the method where the above code exists (a request is coming from UI to the above code, which should then call another API) – rajugaadu Jun 01 '17 at 16:48
  • Sorry ... this was for another member - "Coming to your other question, 'res' is actually the response object for the request which invokes the method where the above code exists (a request is coming from UI to the above code, which should then call another API)" – rajugaadu Jun 01 '17 at 17:21
  • @JonasZell .... could you please have a look at my Edited question? – rajugaadu Jun 07 '17 at 00:56

2 Answers2

10

if you have control over "the other API" too, you could include the image as base64 representation of the binary data in the post-body (and decode it on the API side)

answer to the update 06/06/2017:

according to the screenshot the API requires multipart/formdata. such requests with the "request"-module are documented in https://github.com/request/request#multipartform-data-multipart-form-uploads

quick example (not tested):

var formData = {
  Data: {data: {client: "abc" ...},
  file: fs.createReadStream('testImage_2.jpg'),
};
request.post({url:'<YourUrl>', formData: formData}, function optionalCallback(err, httpResponse, body) {
  if (err) {
    return console.error('upload failed:', err);
  }
  console.log('Upload successful!  Server responded with:', body);
});
Fabian
  • 531
  • 4
  • 11
5

If you add the body to your request with the JSON data, you should be able to send it:

 var options = {
        host: 'hostname.com',
        port: 80,
        path: '/api/content',
        method: 'POST',
        headers:{
            'Content-Type' : 'multipart/form-data'
        },
        body: {
            "data": {"client":"abc","address": "123"},
            "meta":{"owner": "yourself","host": "hostishere"}
        }
 };

What I don't understand is why you have a setTimeout with res.send when there is no res variable defined anywhere.

  • Coming to your other question, 'res' is actually the response object for the request which invokes the method where the above code exists (a request is coming from UI to the above code, which should then call another API). Sorry for missing that in my posted code. – rajugaadu Jun 01 '17 at 17:20
  • are you sure the 'body' can be added to the Http Options? The Node JS documentation on 'options' doesn't list 'body' as a possible property. Nevertheless, I have tried the recommendation and it doesn't seem to work though. – rajugaadu Jun 02 '17 at 18:24
  • could you please have a look at my Edited question? – rajugaadu Jun 07 '17 at 00:56