Ken J
Ken J

Reputation: 4582

NodeJS HTTP Requests Promises and Storing Results in Variables

I'm building a front-end application that makes HTTP requests to 2 separate API's.

http://greetings_api:3000/getGreeting
  data {'language': 'es'}
Response: 'Hola'

http://users_api:3000/getUser
  data {'userid': 1}
Response: 'Jose Smith'

I have a single route that makes a request to these API's and then returns those responses:

var http = require('http');
var request = require('request-promise');

var greetingOptions = {
    uri: 'http://greetings_api:3000/getGreeting',
    hostname: 'greetings_api',
    method: 'POST',
    headers: {
            'Content-Type': 'application/json',
            'language': 'es'
    }
};

var greeting = {
    getGreeting: function() {
        return request(greetingOptions);
    }
}

function myGreeting() {
    return greeting.getGreeting();
};

var userOptions = {
    uri: 'http://users_api:3000/getUser',
    hostname: 'users_api',
    method: 'POST',
    headers: {
            'Content-Type': 'application/json',
            'id': 1
    }
};

var user = {
    getUser: function() {
        return request(userOptions);
    }
}

function myUser() {
    return user.getUser();
};

function getWelcome(req, res) {

    // How do you store this....
    myUser().then(function(result) {
        console.log('result')
        return result;
    })

    // ...and this...
    myGreeting().then(function(result) {
      console.log('Greet ' + result);
        return result;
    });

    /// ...and then send them with this?
    res.send(greeting + ' ' + user);
}

module.exports = { getWelcome };

So with the current code I get the correct output in the console. The problem is that I need to be able to send the response from the route with the combination of both API responses. What is the simplest way to accomplish this?

Upvotes: 0

Views: 1372

Answers (2)

Asaf Aviv
Asaf Aviv

Reputation: 11800

You are sending the response before the promises resolving.

with async/await we can write asynchronous code that looks and behaves like synchronous.

async function getWelcome(req, res) {
  // we can wrap our operation in a try/catch block to handle
  // both asynchronous and synchronous errors
  try {
    // with the await keyword we can wait for all promises to resolve
    // before we continue with our code

    /* if one of the promises inside Promise.all rejects we move to the catch block */
    const [user, greeting] = await Promise.all([
      myUser(),
      myGreeting()
    ]);
    // send the response if no errors
    res.send(greeting + ' ' + user);
    catch(e) {
      res.status(404).send();
    }
}

Upvotes: 1

Rashad Ibrahimov
Rashad Ibrahimov

Reputation: 3319

You need to make 2 parallel requests and send response after completing both. Here Promise.all function can help you.

Promise.all([myUser(), myGreeting()]).then(function(result) {
    // result[0] - user
    // result[1] - greeting
    res.send(result[0] + ' ' + result[1]);
});

Upvotes: 1

Related Questions