Building a weather app is a great way to learn about API integration and data handling in web development. In this article, we will create a weather app using Axios, a popular promise-based HTTP client for JavaScript. Axios makes it easy to fetch data from APIs, handle responses, and manage errors, which are crucial aspects of building a reliable and user-friendly app.
We will use the OpenWeatherMap API to get weather data based on user input. This project will involve setting up the project environment, building the user interface, integrating Axios to fetch data, displaying the weather information, and handling potential errors gracefully. By the end of this article, you’ll have a functional weather app and a solid understanding of how to use Axios for API interactions.
Setting Up the Project
Installing Dependencies
To get started, create a new project directory and navigate into it. Initialize a new Node.js project and install the necessary dependencies, including Axios.
mkdir weather-app
cd weather-app
npm init -y
npm install axios
Basic Configuration
Create the initial project structure with HTML, CSS, and JavaScript files.
touch index.html styles.css app.js
The index.html
file will serve as the main entry point, styles.css
for styling, and app.js
for our JavaScript code.
Building the UI
HTML Structure
Start by creating a basic HTML structure in index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Weather App</h1>
<form id="weather-form">
<input type="text" id="city" placeholder="Enter city name">
<button type="submit">Get Weather</button>
</form>
<div id="weather-info"></div>
</div>
<script src="app.js"></script>
</body>
</html>
This HTML structure includes a form for the user to enter a city name and a div to display the weather information.
CSS for Styling
Add some basic styles in styles.css
:
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background: #f0f0f0;
}
.container {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
text-align: center;
}
input {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
margin-right: 10px;
}
button {
padding: 10px;
border: none;
border-radius: 5px;
background-color: #007BFF;
color: white;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
#weather-info {
margin-top: 20px;
}
This CSS provides basic styling to center the content, style the input and button, and add some visual appeal to the weather information.
Integrating Axios
Setting Up Axios
In app.js
, start by importing Axios and setting up a basic configuration.
import axios from 'axios';
const API_KEY = 'your_openweathermap_api_key'; // Replace with your OpenWeatherMap API key
const BASE_URL = 'https://api.openweathermap.org/data/2.5/weather';
// Select DOM elements
const form = document.getElementById('weather-form');
const cityInput = document.getElementById('city');
const weatherInfo = document.getElementById('weather-info');
This code initializes Axios and sets up constants for the OpenWeatherMap API key and base URL.
Configuring Axios for API Requests
Add an event listener to the form to handle form submissions and make API requests using Axios.
form.addEventListener('submit', async (event) => {
event.preventDefault();
const city = cityInput.value;
try {
const response = await axios.get(BASE_URL, {
params: {
q: city,
appid: API_KEY,
units: 'metric'
}
});
displayWeather(response.data);
} catch (error) {
handleError(error);
}
});
In this code, when the form is submitted, we prevent the default behavior, get the city name from the input, and make a GET request to the OpenWeatherMap API using Axios. If the request is successful, the displayWeather
function is called with the response data. If an error occurs, the handleError
function is called.
Fetching Weather Data
Using the OpenWeatherMap API
The OpenWeatherMap API provides weather data for a given city. To use this API, you need an API key, which you can obtain by signing up on the OpenWeatherMap website.
Code Example: Making a GET Request
The code snippet in the previous section demonstrates how to make a GET request to the OpenWeatherMap API. Here’s the code again for reference:
form.addEventListener('submit', async (event) => {
event.preventDefault();
const city = cityInput.value;
try {
const response = await axios.get(BASE_URL, {
params: {
q: city,
appid: API_KEY,
units: 'metric'
}
});
displayWeather(response.data);
} catch (error) {
handleError(error);
}
});
The axios.get
method initiates a GET request to the OpenWeatherMap API with the specified city name and API key as query parameters. The units
parameter is set to metric
to get the temperature in Celsius. The await
keyword ensures that the function waits for the request to complete before continuing.
Displaying Weather Data
Parsing API Response
Once we receive the weather data from the API, we need to parse it and display it on the UI.
Code Example: Updating the UI
Here’s how to implement the displayWeather
function:
const displayWeather = (data) => {
const weatherHTML = `
<h2>${data.name}, ${data.sys.country}</h2>
<p>Temperature: ${data.main.temp}°C</p>
<p>Weather: ${data.weather[0].description}</p>
<p>Humidity: ${data.main.humidity}%</p>
<p>Wind Speed: ${data.wind.speed} m/s</p>
`;
weatherInfo.innerHTML = weatherHTML;
};
The displayWeather
function takes the API response data as an argument and constructs an HTML string with the relevant weather information, including the city name, temperature, weather description, humidity, and wind speed. This HTML string is then inserted into the weatherInfo
div to update the UI.
Handling Errors
Common Error Scenarios
When making API requests, you may encounter various errors, such as network issues, invalid API keys, or incorrect city names. Handling these errors gracefully is important for providing a good user experience.
Code Example: Error Handling in Axios
Here’s how to implement the handleError
function:
const handleError = (error) => {
let errorMessage = 'An error occurred';
if (error.response) {
// Server responded with a status other than 2xx
if (error.response.status === 404) {
errorMessage = 'City not found';
} else {
errorMessage = `Error: ${error.response.status}`;
}
} else if (error.request) {
// No response received from server
errorMessage = 'No response from server';
} else {
// Other errors
errorMessage = error.message;
}
weatherInfo.innerHTML = `<p class="error">${errorMessage}</p>`;
};
The handleError
function checks the type of error encountered and sets an appropriate error message. If the error response status is 404, it indicates that the city was not found. For other status codes, it displays the status code. If no response was received from the server, it indicates a network issue. Finally, it updates the weatherInfo
div with the error message.
Enhancing the App
Adding a Loading Spinner
To improve the user experience, we can add a loading spinner that appears while the API request is being processed.
Code Example: Implementing Loading State
First, add the loading spinner HTML and CSS:
<!-- In index.html -->
<div id="loading" class="loading-spinner" style="display: none;"></div>
/* In styles.css */
.loading-spinner {
border: 16px solid #f3f3f3;
border-top: 16px solid #007BFF;
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 2s linear infinite;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Update app.js
to show and hide the loading spinner:
const loadingSpinner = document.getElementById('loading');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const city = cityInput.value;
// Show loading spinner
loadingSpinner.style.display = 'block';
try {
const response = await axios.get(BASE_URL, {
params: {
q: city,
appid: API_KEY,
units: 'metric'
}
});
displayWeather(response.data);
} catch (error) {
handleError(error);
} finally {
// Hide loading spinner
loadingSpinner.style.display = 'none';
}
});
In this enhancement, we add a loading spinner that is displayed while the API request is in progress. The spinner is shown when the form is submitted and hidden when the request is completed, whether it is successful or results in an error. The finally
block ensures that the spinner is hidden regardless of the request outcome.
Conclusion
In this article, we built a weather app using Axios to fetch data from the OpenWeatherMap API. We covered setting up the project, building the user interface, integrating Axios for API requests, displaying weather data, handling errors, and enhancing the app with a loading spinner.
The examples and techniques discussed provide a solid foundation for building API-driven applications with Axios. I encourage you to experiment with these concepts and extend the weather app with additional features, such as displaying a weather forecast, using geolocation to get the user’s current location, or adding a search history.
Additional Resources
To continue your learning journey with Axios and web development, here are some additional resources:
- Axios Documentation: The official documentation provides comprehensive information and examples. Axios Documentation
- OpenWeatherMap API: Documentation for the OpenWeatherMap API used in this project. OpenWeatherMap API
- JavaScript Promises: Learn more about promises and asynchronous programming in JavaScript. MDN Web Docs – Promises
- Async/Await: Deep dive into async/await and how it simplifies working with promises. MDN Web Docs – Async/Await
- CSS Flexbox: Learn how to use Flexbox for layout and alignment. MDN Web Docs – Flexbox
By utilizing these resources, you can deepen your understanding of Axios, API integration, and web development techniques to build more sophisticated and robust applications.