Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Axios: chaining multiple API requests

I need to chain a few API requests from the Google Maps API, and I'm trying to do it with Axios.

Here is the first request, which is in componentWillMount()

axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p1)   .then(response => this.setState({ p1Location: response.data }))  } 

Here is the second request:

axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p2)   .then(response => this.setState({ p2Location: response.data })) 

Then we have a third request, which is dependent on the first two being completed:

axios.get('https://maps.googleapis.com/maps/api/directions/json?origin=place_id:' + this.state.p1Location.results.place_id + '&destination=place_id:' + this.state.p2Location.results.place_id + '&key=' + 'API-KEY-HIDDEN')   .then(response => this.setState({ route: response.data })) 

How can I chain these three calls so that the third happens after the first two?

like image 823
Freddy Avatar asked May 25 '17 14:05

Freddy


People also ask

Which method is used to make multiple concurrent requests using Axios?

all is a helper method built into Axios to deal with concurrent requests. Instead of making multiple HTTP requests individually, the axios. all method allows us to make multiple HTTP requests to our endpoints altogether.

How do I create multiple Axios requests?

Since axios returns a Promise we can go for multiple requests by using Promise. all , luckily axios itself also ships with a function called all , so let us use that instead and add two more requests. Again we define the different URLs we want to access.


2 Answers

First off, not sure you want to do this in your componentWillMount, it's better to have it in componentDidMount and have some default states that will update once done with these requests. Second, you want to limit the number of setStates you write because they might cause additional re-renders, here is a solution using async/await:

async componentDidMount() {    // Make first two requests   const [firstResponse, secondResponse] = await Promise.all([     axios.get(`https://maps.googleapis.com/maps/api/geocode/json?&address=${this.props.p1}`),     axios.get(`https://maps.googleapis.com/maps/api/geocode/json?&address=${this.props.p2}`)   ]);    // Make third request using responses from the first two   const thirdResponse = await axios.get('https://maps.googleapis.com/maps/api/directions/json?origin=place_id:' + firstResponse.data.results.place_id + '&destination=place_id:' + secondResponse.data.results.place_id + '&key=' + 'API-KEY-HIDDEN');    // Update state once with all 3 responses   this.setState({     p1Location: firstResponse.data,     p2Location: secondResponse.data,     route: thirdResponse.data,   });  } 
like image 169
Matt Aft Avatar answered Sep 23 '22 03:09

Matt Aft


A little late to the party, but I like this pattern of chaining promises, returning them to keep the promise chain alive.

axios   .get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p1)   .then(response => {     this.setState({ p1Location: response.data });     return axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p2);   })   .then(response => {     this.setState({ p2Location: response.data });     return axios.get('https://maps.googleapis.com/maps/api/geocode/json?&address=' + this.props.p3);   })   .then(response => {     this.setState({ p3Location: response.data });   }).catch(error => console.log(error.response)); 
like image 25
chrisz Avatar answered Sep 23 '22 03:09

chrisz