26 - Weather Forecast App with Location Detection

Description:

Develop a React app that displays weather forecasts for a user's current location or a specified location with the following features:

  • Automatically detects the user's location (with their permission).

  • Allows users to manually enter a location if desired.

  • Fetches weather data from a weather API based on the chosen location.

  • Displays the current weather conditions, including temperature, humidity, wind speed, and weather description.

  • Shows a 5-day forecast with daily high and low temperatures and weather descriptions.

Algorithm

  1. Location Handling:

    • Request user permission to access their location using browser APIs.

    • If granted, use the Geolocation API to retrieve the user's coordinates.

    • Provide a search input for manual location entry.

  2. Weather Data Fetching:

    • Integrate with a weather API (e.g., OpenWeatherMap, Weatherbit, AccuWeather).

    • Fetch weather data based on the user's location or entered location.

    • Parse the API response to extract relevant weather information.

  3. State Management:

    • Define state variables to hold:

      • currentLocation: The user's current location or entered location.

      • weatherData: The fetched weather data, including current conditions and forecast.

      • loading: A boolean indicating whether data is being fetched.

      • error: An error message if fetching fails.

  4. Weather Display:

    • Conditionally render loading indicators or error messages.

    • Display the current weather conditions with relevant information.

    • Show the 5-day forecast in a clear and organized format.

Code

import React, { useState, useEffect } from 'react';

const API_KEY = 'YOUR_API_KEY'; // Replace with your API key

function WeatherForecastApp() {
  const [currentLocation, setCurrentLocation] = useState('');
  const [weatherData, setWeatherData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        const { latitude, longitude } = position.coords;
        setCurrentLocation(`lat=${latitude}&lon=${longitude}`);
        fetchWeatherData(currentLocation);
      },
      (error) => setError(error.message)
    );
  }, []);

  const handleLocationChange = (event) => {
    setCurrentLocation(event.target.value);
  };

  const fetchWeatherData = async (location) => {
    setLoading(true);
    try {
      const response = await fetch(`https://api.openweathermap.org/data/2.5/forecast?${location}&appid=${API_KEY}`);
      const data = await response.json();
      setWeatherData(data);
    } catch (error) {
      setError(error.message);
    } finally {
      setLoading(false);
    }
  };

  if (loading) return <p>Loading weather data...</p>;
  if (error) return <p>{error}</p>;

  const { current, daily } = weatherData;

  return (
    <div className="weather-app">
      {current && (
        <div className="current-weather">
          <h3>Current conditions in {current.city.name}</h3>
          <p>
            Temperature: {Math.round(current.main.temp - 273.15)}°C ({Math.round((current.main.temp - 273.15) * 9 / 5 + 32)}°F)
          </p>
          <p>Humidity: {current.main.humidity}%</p>
          <p>Wind speed: {current.wind.speed} m/s</p>
          <p>Description: {current.weather[0].main}</p>
        </div>
      )}
      {daily && (
        <div className="forecast">
          <h3>5-day forecast</h3>
          {daily.slice(1).map((day) => (
            <div key={day.dt} className="day-forecast">
              <p>{new Date(day.dt * 1000).toLocaleDateString('en-US', { weekday: 'long' })}</p>
              <p>High: {Math.round(day.temp.max - 273.15)}°C ({Math.round((day.temp.max - 273.15) * 9 / 5 + 32)}°F)</p>
              <p>Low: {Math.round(day.temp.min - 273.15)}°C ({Math.round((day.temp.min - 273.15) * 9 / 5 + 32)}°F)</p>
              <p>Description: {day.weather[0].main}</p>
            </div>
          ))}
        </div>
      )}
      <input type="text" placeholder="Enter a location" onChange={handleLocationChange} />
      <button onClick={() => fetchWeatherData(currentLocation)}>Get weather for location</button>
    </div>
  );
}

export default WeatherForecastApp;

Explanation

  • State variables hold current location, weather data, loading status, and error message.

  • useEffect hooks handle initial location detection and weather data fetching.

  • handleLocationChange updates the current location based on user input.

  • fetchWeatherData performs API calls and stores the retrieved data.

  • The UI conditionally renders loading indicators, error messages, and weather information.

  • Current weather and 5-day forecast are displayed with relevant details.

Additional notes

Optionally, add features like:

  • Hourly forecasts for more detailed weather information.

  • Weather alerts for severe weather conditions.

  • Customizable weather preferences (e.g., temperature units).

  • Visually appealing weather visualizations and animations.

Last updated