PROGRAM-15
Aim:- Create a service in react that fetches the weather information
from openweathermap.org and the display the current and weather
information.
Steps to create the application:
Step 1: Set up React project using the below command in VSCode IDE.
npx create-react-app weather
Step 2: Navigate to the newly created project folder by executing the below command.
cd weather
Step 3: As we are using various packages for the project, we need to install them. Use the below
command to install all the packages that are specified in package.json file.
npm install axios react-loader-spinner @fortawesome/react-fontawesome
@fortawesome/free-solid-svg-icons
//App.js
import React from 'react';
import './App.css';
import Weather from './Weather';
function App() {
return (
<div className="App">
<Weather />
</div>
);
}
export default App;
// Weather.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFrown } from '@fortawesome/free-solid-svg-icons';
import './Weather.css';
import { Oval } from 'react-loader-spinner';
const Weather = () => {
const [input, setInput] = useState('');
const [weather, setWeather] = useState({
loading: false,
data: null,
error: false,
});
const [hourlyForecast, setHourlyForecast] = useState({
loading: false,
data: null,
error: false,
});
useEffect(() => {
const fetchWeatherData = async () => {
if (input.trim() === '') return;
setWeather({ loading: true, data: null, error: false });
setHourlyForecast({ loading: true, data: null, error: false });
const url = 'https://api.openweathermap.org/data/2.5/weather';
const forecastUrl = 'https://api.openweathermap.org/data/2.5/forecast';
const apiKey = 'YOUR_API_KEY_HERE'; // Replace with your OpenWeatherMap API key
try {
// Fetch current weather
const currentWeatherResponse = await axios.get(url, {
params: {
q: input.trim(), // Trim whitespace from input
units: 'metric',
appid: apiKey,
},
});
// Fetch hourly forecast
const forecastResponse = await axios.get(forecastUrl, {
params: {
q: input.trim(), // Trim whitespace from input
units: 'metric',
appid: apiKey,
},
});
setWeather({ loading: false, data: currentWeatherResponse.data, error: false });
setHourlyForecast({ loading: false, data: forecastResponse.data, error: false });
setInput(''); // Clear input after successful fetch
} catch (error) {
console.error('Error fetching weather data:', error);
setWeather({ loading: false, data: null, error: true });
setHourlyForecast({ loading: false, data: null, error: true });
}
};
fetchWeatherData();
}, [input]);
const toDateFunction = (timestamp) => {
const date = new Date(timestamp * 1000);
const hours = date.getHours();
const minutes = "0" + date.getMinutes();
return `${hours}:${minutes.substr(-2)}`;
};
const handleSubmit = (event) => {
event.preventDefault();
fetchWeatherData();
};
const fetchWeatherData = async () => {
if (input.trim() === '') return;
setWeather({ loading: true, data: null, error: false });
setHourlyForecast({ loading: true, data: null, error: false });
const url = 'https://api.openweathermap.org/data/2.5/weather';
const forecastUrl = 'https://api.openweathermap.org/data/2.5/forecast';
const apiKey = 'YOUR_API_KEY_HERE'; // Replace with your OpenWeatherMap API key
try {
// Fetch current weather
const currentWeatherResponse = await axios.get(url, {
params: {
q: input.trim(), // Trim whitespace from input
units: 'metric',
appid: apiKey,
},
});
// Fetch hourly forecast
const forecastResponse = await axios.get(forecastUrl, {
params: {
q: input.trim(), // Trim whitespace from input
units: 'metric',
appid: apiKey,
},
});
setWeather({ loading: false, data: currentWeatherResponse.data, error: false });
setHourlyForecast({ loading: false, data: forecastResponse.data, error: false });
setInput(''); // Clear input after successful fetch
} catch (error) {
console.error('Error fetching weather data:', error);
setWeather({ loading: false, data: null, error: true });
setHourlyForecast({ loading: false, data: null, error: true });
}
};
return (
<div className="weather-app">
<h1 className="app-name">React Weather App</h1>
<form onSubmit={handleSubmit}>
<div className="search-bar">
<input
type="text"
className="city-search"
placeholder="Enter city name..."
value={input}
onChange={(e) => setInput(e.target.value)}
/>
<button type="submit" className="submit-btn">
Search
</button>
</div>
</form>
{/* Current weather display */}
{weather.loading && (
<div className="loading-indicator">
<Oval type="Oval" color="black" height={50} width={50} />
</div>
)}
{weather.error && (
<div className="error-message">
<FontAwesomeIcon icon={faFrown} />
<span className="error-text">City not found</span>
</div>
)}
{weather.data && (
<div className="weather-display">
<div className="city-name">
<h2>{weather.data.name}, {weather.data.sys.country}</h2>
</div>
<div className="date">
<span>{toDateFunction(weather.data.dt)}</span>
</div>
<div className="icon-temp">
<img
className="weather-icon"
src={`https://openweathermap.org/img/wn/${weather.data.weather[0].icon}.png`}
alt={weather.data.weather[0].description}
/>
{Math.round(weather.data.main.temp)} <sup className="deg">°C</sup>
</div>
<div className="description">
<p>{weather.data.weather[0].description.toUpperCase()}</p>
<p>Wind Speed: {weather.data.wind.speed} m/s</p>
</div>
</div>
)}
{/* Hourly forecast display */}
{hourlyForecast.loading && (
<div className="loading-indicator">
<Oval type="Oval" color="black" height={50} width={50} />
</div>
)}
{hourlyForecast.error && (
<div className="error-message">
<FontAwesomeIcon icon={faFrown} />
<span className="error-text">Failed to fetch hourly forecast</span>
</div>
)}
{hourlyForecast.data && (
<div className="hourly-forecast">
<h3>Hourly Forecast</h3>
<div className="forecast-items">
{hourlyForecast.data.list.map((item, index) => (
<div key={index} className="forecast-item">
<div className="time">{toDateFunction(item.dt)}</div>
<div className="temp">{Math.round(item.main.temp)} °C</div>
<div className="description">{item.weather[0].description}</div>
</div>
))}
</div>
</div>
)}
</div>
);
};
export default Weather;
/* Weather.css */
.weather-app {
text-align: center;
max-width: 600px;
margin: 0 auto;
}
.app-name {
font-size: 1.5rem;
margin-bottom: 20px;
}
.search-bar {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.city-search {
padding: 10px;
font-size: 1rem;
width: 300px;
margin-right: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.submit-btn {
padding: 10px 20px;
font-size: 1rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.submit-btn:hover {
background-color: #0056b3;
}
.loading-indicator {
margin-top: 20px;
}
.error-message {
margin-top: 20px;
color: #dc3545;
font-size: 1.2rem;
}
.weather-display {
margin-top: 20px;
}
.hourly-forecast {
margin-top: 20px;
}
.forecast-items {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.forecast-item {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 5px;
padding: 10px;
margin: 5px;
text-align: center;
}
.weather-icon {
width: 50px;
height: 50px;
}
.deg {
font-size: 0.8rem;
}
Steps to run the application:
1. Execute the following command in the terminal.
npm start
2. Open the web browser and type the following URL in the address bar.
http://localhost:3000/
Output: