In today’s digital world, access to real-time information is crucial. Weather data, in particular, is something many of us check daily. Building a simple weather application is an excellent project for learning TypeScript. It combines practical coding with the ability to fetch and display data from an external API, giving you hands-on experience with core TypeScript concepts. This tutorial will guide you through creating a basic weather application that fetches weather data from a free weather API and displays it in your browser. By the end of this tutorial, you’ll have a functional application and a solid understanding of how to use TypeScript to interact with APIs, handle data, and build interactive web applications.
What You’ll Learn
- Setting up a TypeScript development environment.
- Working with TypeScript types and interfaces.
- Making HTTP requests using the
fetchAPI. - Parsing JSON data from an API response.
- Displaying data dynamically in the browser.
- Handling errors gracefully.
Prerequisites
Before you begin, you should have a basic understanding of HTML, CSS, and JavaScript. You’ll also need:
- Node.js and npm (Node Package Manager) installed on your system.
- A code editor (like Visual Studio Code) to write your code.
Setting Up Your Project
Let’s start by setting up our project. Open your terminal or command prompt and follow these steps:
- Create a Project Directory: Create a new directory for your project and navigate into it.
mkdir weather-app
cd weather-app
- Initialize npm: Initialize a new npm project. This will create a
package.jsonfile, which will manage your project’s dependencies.
npm init -y
- Install TypeScript: Install TypeScript as a development dependency.
npm install --save-dev typescript
- Initialize TypeScript: Create a
tsconfig.jsonfile. This file configures the TypeScript compiler.
npx tsc --init
This will generate a tsconfig.json file. You can customize this file, but for this tutorial, the default settings will work fine. You may want to uncomment the following lines in your tsconfig.json to enable strict type checking:
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true
- Create Project Files: Create the following files in your project directory:
index.html: The HTML file for your application.src/index.ts: The TypeScript file where you’ll write your code.src/styles.css: The CSS file for styling your application (optional).
Writing the HTML
Let’s start by creating the HTML structure for your application. Open index.html and add the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather App</title>
<link rel="stylesheet" href="src/styles.css">
</head>
<body>
<div class="container">
<h1>Weather App</h1>
<div class="search-box">
<input type="text" id="cityInput" placeholder="Enter city name">
<button id="searchButton">Search</button>
</div>
<div id="weatherInfo">
<!-- Weather information will be displayed here -->
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
This HTML provides the basic structure for your weather application: a heading, a search box (with an input field and a button), and a div to display the weather information. The script tag at the end links to the compiled JavaScript file (src/index.js), which we will generate from our TypeScript code.
Styling with CSS (Optional)
To make your application look more appealing, you can add some CSS. Open src/styles.css and add the following (or your own) styles:
body {
font-family: sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
text-align: center;
}
h1 {
color: #333;
}
.search-box {
margin-bottom: 20px;
}
input[type="text"] {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
margin-right: 10px;
}
button {
padding: 8px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
#weatherInfo {
margin-top: 20px;
}
This CSS provides basic styling for the layout, headings, input fields, and buttons. Feel free to customize the styles to your liking.
Writing the TypeScript Code
Now, let’s write the TypeScript code that will fetch and display the weather data. Open src/index.ts and add the following code:
// Define an interface for the weather data
interface WeatherData {
name: string;
main: {
temp: number;
humidity: number;
};
weather: [{
description: string;
icon: string;
}];
wind: {
speed: number;
};
}
// API Key (replace with your actual API key)
const apiKey = 'YOUR_API_KEY'; // Get your API key from OpenWeatherMap
const apiUrl = 'https://api.openweathermap.org/data/2.5/weather';
// Get references to HTML elements
const cityInput = document.getElementById('cityInput') as HTMLInputElement;
const searchButton = document.getElementById('searchButton') as HTMLButtonElement;
const weatherInfo = document.getElementById('weatherInfo') as HTMLDivElement;
// Function to fetch weather data
async function getWeatherData(city: string): Promise<WeatherData | null> {
const url = `${apiUrl}?q=${city}&appid=${apiKey}&units=metric`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data: WeatherData = await response.json();
return data;
} catch (error: any) {
console.error('Error fetching weather data:', error);
alert(`Error: ${error.message}`); // Display the error to the user
return null;
}
}
// Function to display weather data
function displayWeatherData(data: WeatherData) {
if (!data) {
weatherInfo.innerHTML = '<p>City not found or an error occurred.</p>';
return;
}
const { name, main, weather, wind } = data;
const temperature = main.temp;
const humidity = main.humidity;
const description = weather[0].description;
const icon = weather[0].icon;
const windSpeed = wind.speed;
const weatherHTML = `
<h2>Weather in ${name}</h2>
<p>Temperature: ${temperature}°C</p>
<p>Humidity: ${humidity}%</p>
<p>Description: ${description}</p>
<img src="http://openweathermap.org/img/w/${icon}.png" alt="Weather Icon">
<p>Wind Speed: ${windSpeed} m/s</p>
`;
weatherInfo.innerHTML = weatherHTML;
}
// Event listener for the search button
searchButton.addEventListener('click', async () => {
const city = cityInput.value.trim();
if (city) {
const weatherData = await getWeatherData(city);
displayWeatherData(weatherData);
} else {
alert('Please enter a city name.');
}
});
Let’s break down this code:
- Interfaces: We define a
WeatherDatainterface to structure the data we expect from the API. This is a crucial part of TypeScript, ensuring type safety. - API Key and URL: We store the API key and API URL in constants. Remember to replace
'YOUR_API_KEY'with your actual API key from OpenWeatherMap. - HTML Element References: We get references to the HTML elements (input field, button, and weather info div) using their IDs. The
as HTMLInputElementandas HTMLButtonElementassertions tell TypeScript what type each element is, enabling type checking. getWeatherDataFunction: This asynchronous function takes a city name as input, constructs the API URL, and uses thefetchAPI to make a request to the weather API. It handles potential errors and returns the weather data ornullif an error occurs.displayWeatherDataFunction: This function takes the weather data and dynamically generates HTML to display the information in theweatherInfodiv. It also handles the case where the city is not found or an error occurred.- Event Listener: An event listener is added to the search button. When the button is clicked, it retrieves the city name from the input field, calls
getWeatherDatato fetch the data, and then callsdisplayWeatherDatato display it.
Compiling and Running Your Application
Now that you’ve written the TypeScript code, you need to compile it into JavaScript. In your terminal, run the following command:
tsc src/index.ts
This command compiles src/index.ts into src/index.js. If you have any errors in your TypeScript code, the compiler will show them in the terminal. Once the compilation is successful, you can open index.html in your web browser. You should see the basic layout of your weather application. Enter a city name and click the search button to see the weather information.
Common Mistakes and How to Fix Them
Here are some common mistakes and how to fix them:
- API Key Issue: The most common issue is forgetting to replace
'YOUR_API_KEY'with your actual API key. The API will not return data without a valid key. - Incorrect API URL: Double-check the API URL and ensure it matches the documentation of the weather API you are using.
- Type Errors: TypeScript will catch type errors during compilation. Review the error messages and ensure your code matches the expected types defined in your interfaces. For example, if you try to access a property that doesn’t exist on the
WeatherDatainterface, TypeScript will alert you. - Network Errors: Make sure you have an active internet connection. Also, check the browser’s developer console for any network errors, such as CORS issues (if the API has CORS restrictions).
- Incorrect Element References: Ensure that the element IDs in your TypeScript code match the IDs in your HTML. Typos are a common source of errors.
- Asynchronous Operations: Remember to use
asyncandawaitcorrectly when working with asynchronous operations (like thefetchAPI). If you forget to await the response, you might try to process the data before it’s available.
Key Takeaways
- TypeScript Improves Code Quality: TypeScript’s type checking helps catch errors early and improves the overall quality of your code.
- Interfaces Define Structure: Interfaces are essential for defining the structure of your data and ensuring type safety.
fetchAPI for API Requests: ThefetchAPI is a modern and easy-to-use way to make HTTP requests in JavaScript.- Error Handling is Crucial: Implement robust error handling to handle API errors and provide a better user experience.
- Dynamic DOM Manipulation: Learn to manipulate the DOM dynamically to display and update data in your application.
FAQ
Q: Where can I get an API key?
A: You can get an API key from OpenWeatherMap. You’ll need to create an account and generate an API key from their website.
Q: What if the API returns an error?
A: The getWeatherData function includes error handling. If the API returns an error, the function will log the error to the console and display an error message in the application. Always check the API’s documentation for specific error codes and messages.
Q: Can I add more features to this application?
A: Absolutely! You can add features like:
- Displaying the weather forecast for multiple days.
- Adding a map to show the location of the city.
- Implementing unit conversions (Celsius to Fahrenheit).
- Adding a loading indicator while fetching data.
Q: How do I deploy this application?
A: You can deploy your application to a hosting service like Netlify, Vercel, or GitHub Pages. You’ll need to build your TypeScript code into JavaScript and then deploy the HTML, CSS, and JavaScript files to the hosting service.
Q: Why use TypeScript for a weather application?
A: TypeScript provides several benefits, including improved code readability, easier debugging, and better maintainability. Type checking helps catch errors early, which can save you time and effort in the long run. For a project that interacts with external data (like an API), TypeScript’s ability to define interfaces and enforce type safety is particularly valuable. It helps you ensure the data you’re working with matches the structure you expect.
Building a weather application is a rewarding project that allows you to apply your TypeScript knowledge to a real-world problem. By following this tutorial, you’ve learned how to set up a TypeScript project, fetch data from an API, and display it in a user-friendly way. Remember to experiment with the code, add new features, and explore other weather APIs to deepen your understanding of TypeScript and web development. You’ll find that with each project, your skills and confidence grow. Embrace the learning process, and enjoy the journey of becoming a proficient TypeScript developer!
