0

My controller is using the request package to make server-side HTTP requests to another API. My question is how can I make MULTIPLE of these requests? Here is my current code:

** UPDATED CODE **

module.exports = function (req, res) {
var context = {};
request('http://localhost:3000/api/single_project/' + req.params.id, function (err, resp1, body) {
    context.first = JSON.parse(body);
    request('http://localhost:3001/api/reports/' + req.params.id, function (err, resp2, body2) {
        context.second = JSON.parse(body2); //this line throws 'SyntaxError: Unexpected token u' error
        res.render('../views/project', context);
    });
});

};

I need to make two more of those calls and send the data returned from it to my template...

Can someone help?

Thanks in advance!

3 Answers 3

2
function makePromise (url) {
  return Promise(function(resolve, reject) {

      request(url, function(err, resp, body) {
        if (err) reject(err);
        resolve(JSON.parse(body));
      });

  });
}

module.exprts = function (req, res) {
  let urls = ['http://localhost:3000/api/1st', 
              'http://localhost:3000/api/2st',
              'http://localhost:3000/api/3st'].map((url) => makePromise(url));

  Promise
    .all(urls)
    .then(function(result) {
      res.render('../views/project', {'first': result[0], 'second': result[1], 'third': result[2]});
    })
    .catch(function(error){
      res.end(error);
    });
}

You can use Promise lib in latest nodejs.

Sign up to request clarification or add additional context in comments.

Comments

0

Simple solution

Nest request calls. This is how you can handle the dependency between requests. Just make sure your parameters are unique across scopes if needed.

module.exports = function (req, res) {
    var context = {};
    request('http://localhost:3000/api/1st', function (err, resp1, body) {
        var context.first = JSON.parse(body);
        request('http://localhost:3000/api/2nd', function (err, resp2, body) {
            context.second = JSON.parse(body);
            request('http://localhost:3000/api/3rd', function (err, resp3, body) {
                context.third = JSON.parse(body);
                res.render('../views/project', context);
            });
        });
    });
};

4 Comments

Is this technique blocking or async?
@user1547174 This is async. The call backs fire when the response is returned.
@t3dodson this is executed serially and one failure in chain leads to failure of whole chain, it is better to use promises as it helps to avoud heavy nesting
Talking about a async. Do yourself a favour, avoid this callback hell, and give the npm module async a spin.
0

Simplest way if you use bluebird promise library:

var Promise = require('bluebird');
var request = Promise.promisify(require('request'));

module.exports = function (req, res) {
  var id = req.params.id;
  var urls = [
   'http://localhost:3000/api/1st/' + id,
   'http://localhost:3000/api/2st/' + id,
   'http://localhost:3000/api/3st/' + id
  ];

  var allRequests = urls.map(function(url) { return request(url); });

  Promise.settle(allRequests)
    .map(JSON.parse)
    .spread(function(json1, json2, json3) {
      res.render('../views/project', { json1: json1 , json2: json2, json3: json3  });
    });
});

it executes all requests even if one (or more) fails

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.