Fire a GET request and get the node Stream
Asked Answered
S

1

10

I'm trying to send as formData, a stream from an image I get using request

The problem is that the request is fire after the formData request. Is there any way I can pipe the image request to recognize? but with the freedom of adding parameters to the formData?

e.g:

var req = request({
  method: 'POST',
  url: 'http://www.foo.bar/api/v1/tag/recognize',
  formData: {
    image_file: request('http://visual-recognition-demo.mybluemix.net/images/horses.jpg'),
    param2: 'value2'
  },
  json: true,
});

How do I fire:

request('http://visual-recognition-demo.mybluemix.net/images/horses.jpg') so the response can be used in req

UPDATE: Seems like the Content-Length header is missing in the
http://visual-recognition-demo.mybluemix.net/images/horses.jpg response
and you only get Transfer-Encoding: chunked

More details here

Spillman answered 13/3, 2015 at 19:49 Comment(2)
I'm not sure that the request library would allow you to this via piping but instead you'd just have to use a callback with the body returned from the original request.Gambell
I think this should be handle in the request library. It happens when you don't specify content-length in the first responseSpillman
R
8

Take a look this part of the docs. What you're describing is essentially this block

request.get('http://google.com/img.png').pipe(request.put('some_url'));  

Note the docs

When doing so, content-type and content-length are preserved in the PUT headers.

Also note, request will always return a Stream if you don't specify a callback. If you do provide a callback it tries to convert the response to a String. Use the encoding:null to get it to return raw bytes.
Example -

request({
   url: 'some_url', //your image
   encoding: null  //returns resp.body as bytes
}, callback..)

To chain calls together (run one after the other) , you can nest the callbacks or use promises. For example to run a request after another request completes -

var request = require('request');

//1st
request('first_url', function (error, response, body) {
  if (!error && response.statusCode == 200) {

      //2nd
      request('other_url', function (error, response, body) {   
         //process resp
      });
  }
});  

Or even better, convert the request callback code to Promises. See a promise library like Bluebird on how to do this.

Here's an example with bluebird (uses then to work in an iterative fasion)

var Promise = require("bluebird");
Promise.promisifyAll(require("request"));

request.getAsync('some_url').then(function(resp) {
   request.getAsync('some_other_url').then(..processing code..);
});
Ramakrishna answered 31/3, 2015 at 18:31 Comment(6)
Thanks for the examples and the explanation. If you look at visual recognition service implementation. How do you think I can implement your solution? I want to hide from users the problem of chaining calls. They should use the snippet I'm using for this question.Spillman
If you want the users to be able to pipe in a binary object from an ajax request (say request lib or whatever), you would need to do a refactor of the actual implementation logic of how params is used. You should also (my suggestion) make the usage of a piped in resource be very explicit in the docs. Just taking a glance at your library I would never expect to be able to use an asynchronous response as a parameter (regardless if it was raw bytes or not)Ramakrishna
Basically I just provided an answer of how to chain a promise (using bytes or text response), so you can implement yourself. The above answer explains the process using the request library. But ideally I would think you wouldn't allow a response to be input as a parameter; or if you do, update the docs to very clearly show that option.Ramakrishna
Try playing around with - request({url: 'http://visual-recognition-demo.mybluemix.net/images/horses.jpg', encoding: null})Ramakrishna
@GermanAttanasioRuiz Np, follow me on github if you'd like. Will be putting alot of good examples of Node code continually throughout the year :)Ramakrishna
Thank you! I was providing a callback and was hitting the 500MB string size limit in node. Adding encoding:null solved my problemVortumnus

© 2022 - 2024 — McMap. All rights reserved.