-1

I've been told to use axios but it's asynchronous and will respond before the inner POST request is complete:

var express = require('express');
const axios = require('axios').default;
var router = express.Router();


router.get('/', function (req, res, next) {
    axios({
        url: "https://example.com/api",
        method: "POST",
        data: "Some data"
    }).then(response => {
        console.log(response) // I want to return this
    }).catch(error => {
        console.log(error) // or this
    })
    res.send("Response or error data here")
});

module.exports = router;

Is there a synchronous module I should use?

Ari
  • 2,499
  • 2
  • 24
  • 54
  • Send the response *from the callback*. – jonrsharpe Jul 18 '20 at 08:22
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – jonrsharpe Jul 18 '20 at 08:22
  • If I add a `res.send()` within the `then()` it doesn't ork because it's async and skips to the `res.send()` outside of the post request. – Ari Jul 18 '20 at 08:25
  • Of course, that's why you don't put *any* res.send outside the promise chain. – jonrsharpe Jul 18 '20 at 08:26

2 Answers2

1

Simply pass either response or error to res.json when the axios promise is resolved/rejected:

router.get('/', function (req, res, next) {
  axios({
    url: "https://example.com/api",
    method: "POST",
    data: "Some data"
  }).then(response => {
    res.json(response)
  }).catch(error => {
    res.json(error)
  })
});
antonku
  • 5,707
  • 2
  • 11
  • 17
1

You could try:

var express = require('express');
const axios = require('axios').default;
var router = express.Router();


router.get('/', function (req, res, next) {
    axios({
        url: "https://example.com/api",
        method: "POST",
        data: "Some data"
    }).then(response => {
        console.log() // I want to return this
        res.send(response)
    }).catch(error => {
        console.log(error) // or this
        res.status(500).send({
            message: e.message || "INTERNAL SERVER ERROR"
        });
    })
    
});

module.exports = router;

The res object has scope within the closure of callback you supply in your .then(), so you could call the res.send method from there. Also, make sure to respond with something in the .catch() so if an error occurs, your API responds with something, instead of getting stuck and timing out.

NOTE: The reason I made an object with a message instead of responding with the error object itself, is that I don't know what I may get in error. For instance, if it is an instance of the Error class then there may be trouble in the implicit JSON.stringify() that res.send will run on it, leading to an unhandled promise rejection.

Anuj Pancholi
  • 815
  • 7
  • 12
  • Ah, so by adding a `res` outside of the `POST` request it would skip to that. Removing it makes it wait for a response instead? – Ari Jul 18 '20 at 08:29
  • Yes. See, if you call the function out of the promise chain, it will not wait for the `axios` promise to resolve. BUT, you can call the `res.send` method from *inside* the callback function of the `.then` itself, which is called *only* when the promise successfully resolves. – Anuj Pancholi Jul 18 '20 at 08:32
  • You an also use async-await, which would make your asynchronous code *look* more imperative, but that's a whole other thread. – Anuj Pancholi Jul 18 '20 at 08:34