Weather Dashboard

Build a weather dashboard in JavaScript: the Fetch API, async/await, error handling and a UI that redraws itself from live data.

Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Intermediate Project — Master Fetch API, Async/Await, Error Handling & Dynamic UI

🧠 Project Overview

A Weather Dashboard is one of the best intermediate JavaScript projects because it forces you to work with real APIs, handle async operations, manage loading states, and design error-proof UI.

These skills form the core of modern frontend development, especially for apps that depend on live data:

The project uses OpenWeatherMap, the same API powering millions of weather apps, from basic dashboards to advanced meteorology tools.

By finishing this project, you master:

🎯 Goal

Build a Weather Dashboard that lets the user:

🧩 Core Concepts You Will Learn

This project teaches all the must-know intermediate JavaScript concepts:

• Fetch API

Sending GET requests to remote servers.

• async/await

Clean, readable asynchronous code.

• JSON Parsing

Extracting data from API responses.

• Error Handling

Using try catch around fetch operations.

• Conditional Rendering

Weather icons, temperature displays, backgrounds.

• DOM Manipulation

Updating UI with real live API data.

• State Management

Loading states, error states, previous searches.

⚠️ API Key Required (FREE)

To fetch real weather data, you need a free API key.

How to get it:

💡 Keys can take 5–10 minutes to activate.

💻 Starter Code (Simplified, Clean, Expandable)

This is your fully working Weather Dashboard starter. Add your API key to make live data work. Test it below and see how all the pieces work together!

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather Dashboard</title>

<style>
  body {
    font-family: Arial, sans-serif;
    background: linear-gradient(135deg,#4facfe 0%,#00f2fe 100%);
    min-height: 100vh;
    padding: 20px;
    color: #fff;
  }
  .container {
    max-width: 500px;
    margin: auto;
    background: rgba(255,255,255,0.2);
    padding: 25px;
    border-radius: 12px;
    backdrop-filter: blur(10px);
  }
  input {
    width: 100%;
    padding: 12px;
    border-radius: 6px;
    border: none;
    margin-bottom: 15px;
    font-size: 16px;
  }
  button {
    width: 100%;
    padding: 12px;
    background: #003cff;
    border: none;
    color: white;
    font-size: 18px;
    border-radius: 6px;
    cursor: pointer;
  }
  button:hover { opacity: 0.85; }

  .weather-box { margin-top: 20px; text-align: center; }
  .temp { font-size: 48px; font-weight: bold; }
  .desc { font-size: 22px; margin-top: 5px; }
  .details { margin-top: 20px; font-size: 18px; }
  .loading { text-align:center; margin-top:20px; }
  .error { text-align:center; color:#ff4d4d; margin-top:20px; }
</style>
</head>

<body>

<div class="container">
  <h2>🌤 Weather Dashboard</h2>

  <input id="cityInput" type="text" placeholder="Enter city name...">
  <button onclick="searchWeather()">Search</button>

  <div id="loading" class="loading" style="display:none">Loading...</div>
  <div id="error" class="error"></div>

  <div id="weatherBox" class="weather-box" style="display:none">
    <img id="icon" width="80">
    <div class="temp" id="temp"></div>
    <div class="desc" id="desc"></div>

    <div class="details">
      <div id="humidity"></div>
      <div id="wind"></div>
    </div>
  </div>
</div>

<script>
const apiKey = "YOUR_API_KEY";

async function searchWeather() {
  const city = document.getElementById("cityInput").value.trim();
  const weatherBox = document.getElementById("weatherBox");
  const loading = document.getElementById("loading");
  const error = document.getElementById("error");

  if (!city) {
    error.textContent = "Enter a city name.";
    return;
  }

  loading.style.display = "block";
  error.textContent = "";
  weatherBox.style.display = "none";

  try {
    const url =
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`;

    const res = await fetch(url);
    if (!res.ok) throw new Error("City not found");

    const data = await res.json();

    // Fill UI
    document.getElementById("temp").textContent = `${data.main.temp}°C`;
    document.getElementById("desc").textContent = data.weather[0].description;
    document.getElementById("humidity").textContent = `Humidity: ${data.main.humidity}%`;
    document.getElementById("wind").textContent = `Wind: ${data.wind.speed} km/h`;

    const iconCode = data.weather[0].icon;
    document.getElementById("icon").src =
      `https://openweathermap.org/img/wn/${iconCode}@2x.png`;

    weatherBox.style.display = "block";

  } catch (err) {
    error.textContent = err.message;
  }

  loading.style.display = "none";
}
</script>

</body>
</html>

🚀 Deep Enhancement Ideas (Turn This Into a Full App)

These features take your dashboard from "beginner project" to portfolio ready:

🔮 1. 5-Day Forecast

Use: https://api.openweathermap.org/data/2.5/forecast

This teaches: Array filtering, Grouping forecast points, Card-based UI

📍 2. Geolocation Detection

Auto-detect the user's city:

navigator.geolocation.getCurrentPosition(success, error);

This makes your app feel premium.

🕒 3. Hourly Temperature Graph

Use a simple canvas chart: Chart.js or your own SVG graph

Shows mastery of: Data visualization, Parsing JSON arrays, Rendering dynamic graphics

💾 4. Recent Searches

Store them in localStorage:

localStorage.setItem("recent", JSON.stringify(list));

Display as clickable buttons.

🔄 5. Unit Toggle

Switch between °C and °F

Formula: F = C × 1.8 + 32

Add a UI toggle button.

🎨 6. Dynamic Backgrounds

Change background depending on data:

This creates an immersive feel.

📌 Perfect Completion Checklist

Your Weather Dashboard should:

Related lessons