I've just started a simple weather-app project to train React and data fetching.
import React, { Component } from 'react';
import './App.css';
import axios from 'axios';
class App extends Component {
constructor(props) {
super(props);
this.state = {
city: "",
id: 0
}
this.choseCity = this.choseCity.bind(this);
this.cityName = this.cityName.bind(this);
this.cityInfo = this.cityInfo.bind(this);
}
chooseCity(e) {
console.log(e.target.value)
this.setState({
city: e.target.value
});
}
cityName() {
axios.get(`https://www.metaweather.com/api/location/search/?query=${this.state.city}`)
.then(res => res.data)
.then(data => this.setState({
city: data[0].title,
id: data[0].woeid}))
}
cityInfo() {
axios.get(`https://www.metaweather.com/api/location/${this.state.id}/`)
.then(res => console.log(res.data))
}
render() {
return (
<div className="App">
<input type="text" placeholder="Enter city name" value={this.state.city} onChange={this.chooseCity}/>
<button onClick={this.cityName}>Name</button>
<button onClick={this.cityInfo}>Info</button>
</div>
);
}
}
export default App;
So, I have 2 functions (cityName and cityInfo) that I'm able to execute on 2 different onClick events. They both seem to work independently.
cityName() requests data that is stored in my state.
cityInfo() uses this state in the url of the request to get further informations.
I'm trying to chain them to be able to retrieve all the data in one call, but since they're both async, my second request starts before the data from the first one is stored in my state, and there is no way in the api I can directly get the info I need in one request.
I've tried a couple of things like grouping them in a single function, but nothing conclusive so far.
Solution: by @elsyr
this is how to chain in one function, using data between the requests:
cityInfo() {
axios.get(`https://www.metaweather.com/api/location/search/?query=${this.state.city}`)
.then(res => res.data)
.then(data => {
axios.get('https://www.metaweather.com/api/location/' + data[0].woeid)
.then(res => res.data)
.then (data => this.setState({
info: data
}))
});
}