Weather App
Updated: 05/19/20
I recently started learning React after many different attempts. I had tried before, but never really put it to use. I wanted to change that. I wanted to make a web app that gets real data from an API. I really like weather, so this was an easy decision.
It’s not really useful considering how many other weather applications are way better, but it was fun making it! I use the Zip Code API to get the coordinates from a zip code and Dark Sky to get the weather data. Made with React (of course!) and hosted on Netlify.
Update: Dark Sky was recently bought by Apple and the API is going away in 2020. Sadness.
Getting The Weather
The Dark Sky API needs the coordinates to get weather data. The first call takes input for a zip code and converts to lat/long and sets the state for long, lat, city, and state. The latitude and longitude is then used to make the call for weather data.
getWeather = () => {
axios.get(`https://cors-anywhere.herokuapp.com/https://www.zipcodeapi.com/rest/Vx2iDKzTlE0ApfqiPcQDVmdgU88QqB0eNkE1jyjlWOoS0MPWa7gUEsopeSY5WiwD/info.json/${this.state.zipcode}/degrees`)
.then(res => {
let presentState = {...this.state};
presentState.location.long = res.data.lng;
presentState.location.lat = res.data.lat;
presentState.location.city = res.data.city;
presentState.location.state = res.data.state;
this.setState({ ...presentState });
}).catch(err => {
console.log(err);
})
.then(() => {
axios.get(`https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/895d852c061ef91db419f40459c25d83/${this.state.location.lat},${this.state.location.long}`)
.then(res => {
let presentState = {...this.state};
presentState.currentTemp = res.data.currently.temperature;
presentState.currentSummary = res.data.currently.summary;
presentState.currentIcon = res.data.currently.icon;
presentState.currentTime = res.data.currently.time;
presentState.hourlySummary = res.data.hourly.summary;
this.setState({ ...presentState });
this.setState({ loaded: true});
}).catch(err => {
console.log(err);
})
})
}
The getWeather()
function is called on submit. Also setting the state to submitted, but not loaded until after all data has been fetched.
handleSubmit(event) {
this.getWeather();
this.setState({submitted: true});
this.setState({loaded: false});
event.preventDefault();
}
The data is then displayed updating the props for components I made for each section of the card.
<div className="uk-flex uk-flex-center">
<div className="uk-card uk-card-secondary uk-card-small uk-card-body uk-width-1-2">
<City city={this.state.location.city} state={this.state.location.state} />
<Summary summary={this.state.currentSummary} icon={this.state.currentIcon} />
<Temperature temp={Math.round(this.state.currentTemp)} />
<p>{this.state.hourlySummary}</p>
</div>
</div>
City
class City extends Component {
render() {
return (
<div className="uk-card-title">
<h2>{this.props.city}, {this.props.state}</h2>
</div>
)
}
}
Summary
class Summary extends Component {
render() {
return (
<div>
<WeatherIcon icon={this.props.icon} />
<p className="uk-text-lead" >{this.props.summary}</p>
</div>
)
}
}
WeatherIcon is another component with a switch to display icons depending on what weather it is
Temperature
class Temperature extends Component {
render() {
return (
<div>
<p className="uk-text-lead">{this.props.temp}°F</p>
</div>
)
}
}
Future Improvements
- Get current location instead of typing zip code in
- Allow input for cities and zip codes
- Update design
- Display more data
- Find new API for weather data
More posts