Weather App with JavaScript by Cristian Villafane

Weather App: A Javascript Tutorial by Cristian Villafane

A practical guide to connecting to a live API, handling data, and building a dynamic, real-world application.

Connecting your application to data from the real world is a fundamental skill for any web developer. A weather app is the perfect project for this, teaching you how to communicate with external services and display live information. This project is a fantastic exercise to master HTML, CSS, and the asynchronous capabilities of JavaScript. In this guide on Javascript by Cristian Villafane, we will build a functional and beautiful weather app from the ground up.

Phase 1: The Structure – HTML for the Interface

Every web application starts with a solid HTML structure. For our weather app, the HTML will define the user input area and the display for the weather data. We’ll need an input field for the city, a button to initiate the search, and a card to show the results. Now, we’ll also add a container for autocomplete suggestions.

Designing the User Interface

We begin with a main container. Inside, we’ll create a search area with an input and a button, a container for autocomplete suggestions, and a display card for the results. The user interface will consist of:

  • City Input: An <input type="text"> allows the user to type the name of a city. It will now trigger a search for city suggestions as the user types.
  • Search Button: A <button> with a search icon is now integrated into the input field for a cleaner look.
  • Autocomplete List: A <div> that will be dynamically populated with city suggestions from the API.
  • Display Card: A dedicated <div> will hold all the weather information: city name, local time, temperature, icon, condition, and other details like humidity, feels like temperature, and wind speed.
<!-- Search Container -->
<div class="search-container">
  <input type="text" id="city-input" placeholder="Enter city name...">
  <button id="search-btn">
    <!-- SVG Search Icon -->
  </button>
  <div class="autocomplete-suggestions" id="autocomplete-list"></div>
</div>

<!-- Weather Display -->
<div class="weather-display" id="weather-display">
  <!-- Content injected by JS -->
</div>

Phase 2: The Logic – Fetching and Displaying API Data

This is where our application comes to life. The JavaScript will listen for user input, make requests to the WeatherAPI, parse the response, and update the HTML to show the current weather conditions.

Understanding the API Response (JSON)

When we make a successful request to the API, it sends back a large block of text in JSON (JavaScript Object Notation) format. Our script then parses this text into a JavaScript object that we can easily work with. A simplified version of this object looks like this:

{
  "location": {
    "name": "London",
    "country": "United Kingdom",
    "localtime": "2023-10-27 13:00"
  },
  "current": {
    "temp_c": 12.0,
    "feelslike_c": 11.2,
    "humidity": 75,
    "wind_kph": 15.1,
    "uv": 3.0,
    "condition": {
      "text": "Partly cloudy",
      "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png"
    }
  }
}

To access a piece of data, we use dot notation. For example, to get the temperature in Celsius, we would access data.current.temp_c, where data is the variable holding our parsed JSON object. To get the condition text (“Partly cloudy”), we need to go deeper: data.current.condition.text.

Customizing the Displayed Information

The best part of using an API is that you can choose exactly what to show. Let’s say you want to add the UV Index to our display.

  1. Find the data: Looking at the JSON above, the UV index is at current.uv.
  2. Add an HTML element: In our `displayWeather` function, we add a new `div` inside the `weather-details` section to hold this information.
    <div class="detail-item">
      <div class="detail-label">UV Index</div>
      <div class="detail-value">${current.uv}</div>
    </div>
  3. That’s it! By adding that snippet to our template literal in the JavaScript, the UV index will now appear on the card. The process is the same for any other data point you want to add. To remove an item, simply delete its corresponding `div` from the template.

Customizing the API Request (Language)

WeatherAPI allows us to customize the request using URL parameters. One of the most useful is `lang`, which changes the language of certain text fields in the response, like the weather condition.

In our code, the API URL is constructed like this:

const apiUrl = `https://api.weatherapi.com/v1/forecast.json?key=${apiKey}&q=${city}&lang=en`;

The part &lang=en tells the API to return the condition text in English (e.g., “Partly cloudy”). If you wanted the text in Spanish, you would simply change it to &lang=es. If you wanted French, you would use &lang=fr. This makes it easy to internationalize your application. The labels on your card (like “Humidity” or “Wind”) are hardcoded in our HTML template, so you would need to change those manually to match the language you choose.

Phase 3: Interactivity and Performance Optimization

A great app feels responsive and fast. We’ll connect our logic to user events and ensure the experience is smooth by using the same performance optimizations from the original template, such as non-blocking font loading.

Event Listeners and User Experience

We now have multiple event listeners: one for the `input` event on the text field to handle autocomplete, another for the `click` event on the search button, and a listener for the `Enter` key. We also handle clicks on the suggestion items to trigger a weather search. A default city is still loaded on page open to provide an immediate example.

Weather App in Action

Below, you can try out the live weather app. Enter a city name and see the new design, the added information, and the autocomplete functionality for yourself. This is the final result of applying the concepts from this tutorial.

The Complete Weather App Code

Here is the self-contained, performance-optimized code for the weather app component. You can copy and paste this into your own project. Remember to replace 'YOUR_API_KEY' with your actual key from WeatherAPI.com.

<!-- HTML Structure -->
<div class="weather-container">
    <div class="search-container">
        <input type="text" id="city-input" placeholder="Enter a city..." aria-label="City Name">
        <button id="search-btn" aria-label="Search">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
        </button>
        <div class="autocomplete-suggestions" id="autocomplete-list"></div>
    </div>
    <div id="weather-display" class="weather-display">
        <!-- Weather data will be dynamically inserted here -->
    </div>
</div>

<!-- JavaScript Logic -->
<script>
// NOTE: This script block is for demonstration purposes only in this complete code view.
// In a real implementation, you would have a single script block at the end of your page
// to handle all interactivity, as shown in the final script of this document.
document.addEventListener('DOMContentLoaded', () => {
    const apiKey = 'YOUR_API_KEY'; // Replace with your key
    const cityInput = document.getElementById('city-input');
    const searchBtn = document.getElementById('search-btn');
    const weatherDisplay = document.getElementById('weather-display');
    const autocompleteList = document.getElementById('autocomplete-list');

    // ... (rest of the functions: fetchWeather, displayWeather, etc.)
});
</script>

I hope you found this tutorial on Javascript by Cristian Villafane useful. Building a weather app not only reinforces your knowledge of asynchronous JavaScript, but it also provides a practical foundation for working with any third-party API. Use this project as a starting point to explore and add new features, like a multi-day forecast or geolocation. The only limit is your curiosity! 🌦️

Happy coding, Cristian Villafane