I am trying to learn Angular/node & express. I am currently attempting to write an endpoint for my backed that
- Needs to use axios to run a get request to an external API that will return a list of IDs (numbers)
- For each of those IDs supplied run a request that gets the details based off that id.
But my question is in regards to number 2. I have a list of IDs as input, and I'd like to run a request to an external API (using axios) based on each of these IDs. It may be helpful to note - The request to an external API based on the ID returns an object with details of that ID so my overall goal with this endpoint of my API is to return an array of objects, where each object contains the details of the IDs.
There have been a couple questions similar to mine...
- Pushing responses of axios request into array (This one is very similiar to my question)
- Axios random number of requests
However, they are using React.js, and I am having difficulties adapting their solution to node/express.
I am trying to model my approach based off of the code snippet provided in the top asnwer of the first question. But, my solution is returning an empty object as a response.
My question: What can I do differently to make multiple axios GET requests to an external API where each request is created dynamically
app.route('/test').get((req, res) => {
axios
.get('https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=vodka')//This will not be hardcoded, but grabbed as a parameter from the endpoint
.then(function(response) {
//Purpose of this initial .then() clause is to make a call to the cocktaildb API to get the IDs of all the cocktails with a given ingredient eg: vodka.
var data = response.data;//response.data contains the JSON object containing the contents received by the cocktaildb API request.
var cocktailIds = [];
//collect all cocktail ids so we can later make more requests to obtain the details associated with that ID.
data.drinks.forEach(drink => {
cocktailIds.push(drink['idDrink']);
});
//this is passed on to the next then clause. It is a list of cocktail ids.
return cocktailIds;
})
.then((drinks) => {
//the promises variable contains a list of all the requests we will have to make in order to get the details of all cocktail ids. I have tested that they are valid requests.
const promises = drinks.map(id => {
//console.log(getCocktailDetailsUrl + id);
return axios.get(getCocktailDetailsUrl + id)
.then(({data}) => {
return data;
})
})
//I was hoping Promise.All to execute all of the requests in the promise and response to be stored in the cocktailDetails variable
const cocktailDetails = Promise.all(promises)
.then(values => {
return values;
})
.catch(error => {
console.log("There was an error when sending requests for details of all cocktails");
console.log(error);
})
//Sending response only formatted this way for testing purposes
if(cocktailDetails) {
//this block is executed, and an empty object is returned as response
console.log("cocktails was sent as response");
res.send(cocktailDetails);
} else {
console.log("cocktails was not sent as response");
res.send("cocktailDetails was not poppulated at the time of sending response");
}
})
.catch(function (error) {
res.send("There was an iswsue with your request to the cocktaildb API.");
console.log('The following is the error from the request to the cocktaildb API: ' + error);
})
});
As I mentioned before, my response contains an empty object. I know I must use promise.all somehow, but I am not sure how to implement it properly.
bluebirdinstalled and assigned toglobal.Promiseor just required asconst Promise = require('bluebird')? AFAIK Promise.all is not available in node.jsPromise.all(promises) .then(values => { console.log(values[0]); return values; })I actually get the desired response I wanted from the first request in the list of requests I plan to make. But, I thought I would be getting the response data to be stored inconst cocktailDetails. I need to figre out how to gain access to the response outside of that.then()