I need to make multiple requests with Axios but I dont know how many, the number of requests is totally random and it could be 0 or 1 or 9182379, and after they are all done I need to do something, as if now I have to update my state(array of objects).
Do you have any idea how could I do this ??
let oldTickets = [...this.state.playedTickets];
let length = oldTickets.length;
let newTickets = [];
for (let index = 0; index < length; index++) {
let currentTicket = oldTickets[index];
// just imported function that returns axios.get call
checkTickets(currentTicket.ticketNumber)
.then(data => {
let newTicket = {
bla: bla
}
newTickets.push(newTicket);
this.setState({playedTickets: newTickets})
})
.catch(err => {
console.log(err);
})
}
This is working fine but I know it's not good, so I am searching for better solution!
after they are all done I need to do something
You can map the array to promises and use Promise.all
:
Promise.all( // executes all requests in parallel
this.state.playedTickets.map(({ ticketNumber }) => checkTickets(ticketNumber))
).then(playedTickets => { // or declare function as `async` and use `await`
// executed only after all requests resolved
console.log('tickets', playedTickets);
this.setState({ playedTickets });
}).catch(e => console.log(e)); // executed as soon as one request fails
EDIT:
continue awaiting for all requests even if some failed, and set the state based on the results of the successful requests
To achieve this, simply catch the error before passing to Promise.all
:
Promise.all(
this.state.playedTickets.map(({ ticketNumber }) =>
checkTickets(ticketNumber).catch(console.log)
)
).then(playedTickets => {
console.log('tickets', playedTickets);
this.setState({ playedTickets });
});
Failed requests will have undefined
as the value in the array.
If required, you can filter them out with
const validTickets = playedTickets.filter(ticket => ticket !== undefined)