Project Idea: Weather Dashboard
This is a perfect project to understand how to work with Third-Party APIs. We will build a simple dashboard where a user can search for any city name, and our app will call an external API (like OpenWeatherMap) to fetch and display the current temperature, humidity, and weather conditions. With this project, you will master asynchronous JavaScript and handling API data.
✨ Key Features
- A search bar for the user to search for a city name.
- Display live data fetched from the API (Temperature, Weather, Humidity, Wind Speed).
- Loading state (while data is being fetched).
- Error handling (if the city is not found or the API fails).
💻 Tech Stack & Skills
- Tech Stack: React, REST API (e.g., OpenWeatherMap), Async/Await.
- Skills Practiced: Third-Party API Integration, Asynchronous JavaScript (`fetch`, `async/await`), State Management (handling loading, error, and data states), Error Handling, Conditional Rendering.
🛠️ Full Step-by-Step Tutorial
Let's build this app from scratch. We assume you have a basic React app running.
Step 1: Get Your API Key
This is the most important step. Without an API key, you can't fetch data.
- Go to OpenWeatherMap API.
- Sign up for a free account.
- Go to your account dashboard and find your "API keys" section.
- Copy the default key. We will use this in our project.
Important: To keep your API key secret, create a file named .env in your project's root folder and add your key like this:
REACT_APP_WEATHER_API_KEY=your_api_key_here
Restart your React app (npm start) after creating this file.
Step 2: Create the Component Files
In your src folder, create a new folder named components. Inside it, create two files:
Weather.js(Our component logic)Weather.css(For styling)
Step 3: The React Component (Weather.js)
This is the main file. We'll add the logic for state, API fetching, and the HTML (JSX).
src/components/Weather.jsimport React, { useState } from 'react';
import './Weather.css';
function Weather() {
// State variables
const [city, setCity] = useState('');
const [weatherData, setWeatherData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
// Get the API key from the .env file
const apiKey = process.env.REACT_APP_WEATHER_API_KEY;
// Function to fetch weather data
const fetchWeather = async () => {
if (!city) {
setError("Please enter a city name.");
return;
}
setLoading(true);
setError(null);
setWeatherData(null);
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`
);
if (!response.ok) {
throw new Error('City not found. Please try again.');
}
const data = await response.json();
setWeatherData(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
// Handle 'Enter' key press in the input
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
fetchWeather();
}
};
return (
Weather Dashboard
setCity(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Enter city name..."
/>
{/* --- Display Area --- */}
{loading && Loading data...
}
{error && {error}
}
{weatherData && (
{weatherData.name}, {weatherData.sys.country}
{Math.round(weatherData.main.temp)}°C
{weatherData.weather[0].description}
Humidity: {weatherData.main.humidity}%
Wind: {weatherData.wind.speed} m/s
Feels like: {Math.round(weatherData.main.feels_like)}°C
)}
);
}
export default Weather;
Step 4: The Styling (Weather.css)
This CSS will make our component look clean and match your site's dark theme.
src/components/Weather.css.weather-container {
max-width: 500px;
margin: 40px auto;
padding: 30px;
background-color: #0f172a; /* Dark card background */
border-radius: 12px;
border: 1px solid #1e293b;
color: #cbd5e1;
font-family: 'Inter', sans-serif;
}
.weather-title {
text-align: center;
color: #fff;
margin-bottom: 25px;
}
.search-bar {
display: flex;
gap: 10px;
margin-bottom: 25px;
}
.search-bar input {
flex-grow: 1;
padding: 12px 15px;
font-size: 1rem;
border-radius: 8px;
border: 1px solid #334155;
background-color: #1e293b;
color: #fff;
}
.search-bar input::placeholder {
color: #64748b;
}
.search-bar button {
padding: 12px 20px;
font-size: 1rem;
font-weight: 700;
border: none;
border-radius: 8px;
background: linear-gradient(90deg, #a78bfa, #f472b6); /* Your site's gradient */
color: #fff;
cursor: pointer;
transition: opacity 0.2s;
}
.search-bar button:hover {
opacity: 0.9;
}
.loading-text, .error-text {
text-align: center;
font-size: 1.1rem;
padding: 20px;
}
.error-text {
color: #f87171;
background-color: #f8717120;
border-radius: 8px;
}
.weather-card {
background-color: #1e293b;
border-radius: 10px;
padding: 25px;
text-align: center;
}
.weather-card h2 {
color: #fff;
font-size: 1.8rem;
margin-bottom: 10px;
}
.weather-main {
display: flex;
align-items: center;
justify-content: center;
margin: 10px 0;
}
.weather-main .temp {
font-size: 4rem;
font-weight: 700;
color: #fff;
margin-left: 10px;
}
.weather-main img {
width: 100px;
height: 100px;
}
.description {
font-size: 1.2rem;
text-transform: capitalize;
color: #94a3b8;
margin-bottom: 20px;
}
.weather-details {
display: flex;
justify-content: space-around;
color: #fff;
}
.weather-details p {
margin: 0;
}
.weather-details strong {
color: #94a3b8;
display: block;
font-size: 0.9rem;
margin-bottom: 5px;
}
Step 5: Add to App.js
Finally, go to your src/App.js file, import the new component, and add it.
import React from 'react';
import './App.css'; // Or your main stylesheet
import Weather from './components/Weather';
function App() {
return (
{/* You can add this component to your homepage
or wherever you want it to appear */}
);
}
export default App;
Aur bas! Ab aapke paas ek fully functional weather app hai. Yeh tutorial ab `project-weather-app.html` page ka hissa hai.
🔥 Next Steps & Challenges
After completing this tutorial, try these ideas:
- **5-Day Forecast:** OpenWeatherMap's API can also send a 5-day forecast. Try to fetch and display that!
- **Geolocation:** Show the weather for the user's current location (using the browser's Geolocation API) on initial page load.
- **Save Last Search:** Save the user's last searched city in `localStorage` so it becomes the default location when the app opens.