METAR/TAF Report App Project

*This is just a screenshot.
The actual demo piece and Github repository linkes are located below
What is METAR / TAF?
In aviation, METAR and TAF are standardized formats used worldwide for reporting weather conditions, primarily for flight planning and operations:
METAR (Meteorological Aerodrome Report)
What it is: A current weather observation report, issued at regular intervals (usually every hour).
Purpose: Provides real-time weather conditions at an airport.
Used by: Pilots, dispatchers, air traffic controllers, and meteorologists.
Includes:
Wind direction and speed
Visibility
Cloud coverage and ceiling
Temperature and dew point
Atmospheric pressure (altimeter setting)
Significant weather phenomena (e.g., rain, thunderstorms)
Runway conditions (sometimes)
Remarks (e.g., lightning observed, pressure falling rapidly)
Example:
METAR KDEN 231753Z 09008KT 10SM FEW030 SCT050 BKN100 21/10 A3012 RMK AO2
TAF (Terminal Aerodrome Forecast)
What it is: A forecast of expected weather conditions at an airport, typically covering a 24- to 30-hour period.
Purpose: Helps pilots anticipate upcoming conditions at departure, en route, alternate, and destination airports.
Issued: Usually 4 times a day (every 6 hours).
Includes:
Forecasted wind direction and speed
Visibility
Weather phenomena
Cloud coverage and ceiling
Probability of certain conditions (e.g., 40% chance of thunderstorms)
Overview
The METAR/TAF project is a web-based tool that allows users to retrieve and display real-time aviation weather reports (METAR) and forecasts (TAF) for any airport using its ICAO code. It leverages the CheckWX API as the data source.
User Input: Users enter an ICAO airport code (e.g., KJFK for JFK Airport) into a form.
API Integration: The app fetches both TAF (Terminal Aerodrome Forecast) and METAR (Meteorological Aerodrome Report) data from the CheckWX API using the provided ICAO code.
Data Display:
TAF: Shows the raw TAF text, issue time, validity period, wind, visibility, and cloud cover from the forecast.
METAR: Shows the raw METAR text, temperature, wind, visibility, and cloud cover.
Error Handling:
If the ICAO code is invalid or the API call fails, the app displays an error message.
The primary objective of this project is to develop proficiency in interfacing with external APIs, retrieving structured data from open-source sources, and programmatically parsing and presenting the results in a user-friendly application.
Programming Languages / Libraries / Frameworks / Databases Used
HTML, CSS, and Vanilla JavaScript.
How does it work (Workflow)?
async function getTafMetar() {
console.log("Function is running...");
The block above declares an asynchronous function (so you can use await inside it) and logs to the console that the function has started.
const icaoCode = document.getElementById("tafInput").value.trim().toUpperCase();
if(!icaoCode) {
alert("Please enter a valid ICAO airport code");
return;
}
Gets the value from an input field with id tafInput, trims whitespace, and converts it to uppercase (ICAO codes are always uppercase). If the input is empty, it alerts the user and exits the function.
const apiKey = "SECRET (Actual API Key Hidden)";
This project is using an API with "https://api.checkwx.com/" for fetching actual METAR/TAF data.
This line stores your CheckWX API key for use in the HTTP request headers.
const tafResponse = await fetch(`https://api.checkwx.com/taf/${icaoCode}/decoded`, {
headers: { "X-API-Key": apiKey },
});
const metarResponse = await fetch(`https://api.checkwx.com/metar/${icaoCode}/decoded`, {
headers: { "X-API-Key": apiKey },
});
This snippet makes 2 asyncrhonous HTTP GET requests to CheckWX API which is one for TAF and the other is for METAR. API Key should be included in the headers. As seen above, these lines are for decoded TAF/METAR messages which is human-readable, structured JSON object with fields like raw_text, timestamp, forecast, wind, visibility, clouds, etc. Without '/decoded', the API returns raw string (this is the actual version used in aviation). For the real world application, all pilots should know how to decode raw TAF/METAR information, however, this is just an app version aimed for regular user UI experiences.
if (!tafResponse.ok || !metarResponse.ok) {
throw new Error(`HTTP error! Status: ${tafResponse.status}`);
}
if tafResponse is not OK or metarResponse is not OK (not responding or any issues), it should show a new error message with Status tafResponse.status.
This is for checking if either API response was unsuccessful (in order to make the app work normally, both API response must be successful) if so, it throws an error message by the 'try and catch' block.
const tafData = await tafResponse.json(); // Convert response to JSON
const metarData = await metarResponse.json();
This block converts the raw HTTP response into objects for easier data access (variables tafData and metarData)
document.getElementById("metar").innerHTML =
metarData.data.length > 0 // "which means if the data exists"
? `<strong>METAR:</strong> ${metarData.data[0].raw_text}
<p><strong>Temperature:</strong> ${metarData.data[0].temperature.celsius}°C (${metarData.data[0].temperature.fahrenheit}°F)
<p><strong>Wind:</strong> ${metarData.data[0].wind.degrees}° at ${metarData.data[0].wind.speed_kts} knots
<p><strong>Visibility:</strong> ${metarData.data[0].visibility.miles} miles
<p><strong>Cloud Cover:</strong> ${metarData.data[0].clouds[0].text} at ${metarData.data[0].clouds[0].base_feet_agl} feet AGL`
: `<strong>TAF:</strong> Data not available.`;
If TAF data is available, formats and displays it in the HTML element with id taf. This part corresponds with HTML snippet "<div id="metar"></div>" in HTML file. The JavaScript code finds the element with id="metar" in the HTML then sets the .innerHTML of the element.
<p><strong>TAF Issued:</strong> ${tafData.data[0].timestamp.from}
<p><strong>Valid Period:</strong> ${tafData.data[0].timestamp.to}
<p><strong>Wind:</strong> ${tafData.data[0].forecast[0].wind.degrees}° at ${tafData.data[0].forecast[0].wind.speed_kts} knots
<p><strong>Visibility:</strong> ${tafData.data[0].forecast[0].visibility.miles} miles
<p><strong>Cloud Cover:</strong> ${tafData.data[0].forecast[0].clouds[0].text} at ${tafData.data[0].forecast[0].clouds[0].base_feet_agl} feet AGL.`
The [0] indicates the first element in TAF array returned by API which has a pattern of:
{
"data": [
{
"raw_text": "TAF KJFK 121130Z 1212/1318 ...",
"timestamp": {
"from": "2024-06-12T12:00:00Z",
"to": "2024-06-13T18:00:00Z"
},
"forecast": [
{
"wind": { "degrees": 180, "speed_kts": 10 },
"visibility": { "miles": 6 },S
"clouds": [
{ "text": "broken", "base_feet_agl": 2500 }
]
}
]
}
]
}
tafData.data is an array with one object (the TAF report).
tafData.data[0] is that first (and only) TAF report object. For example, "metarData.data[0].temperature.celsius}" will display "Temperature: 27°C" corresponding with: "<p><strong>Temperature:</strong> 27°C". Also METAR report works the exactly same way since the app is fetching data from same API source which returns in the same format.

The actual display of returned actual and real-time API information.
MISC
The two buttons at the bottom currently serve as external links to Federal Aviation Administration informational resources. However, with the integration of additional API sources, the application could be extended to include new sections that display related data directly within the interface.

API fail!
I've attempted to implement a feature showing TFR (Temporary Flight Restriction) which is a vital part of NOTAM (Notes TO Airmen) every pilot checks before flight as users input ICAO code. However, the data API is not working properly at least for now.

What would be pros and cons (and possible future improvements)?
Pro1:Fetches live weather and NOTAM/TFR data, which is highly valuable for pilots, dispatchers, and aviation enthusiasts.
Pro2: Integrates two APIs (CheckWX for weather, AeroDataBox for NOTAMs), providing a more comprehensive view.
Pro3: Allows users to enter any ICAO code, not just a fixed airport.
Pro4: Provides user feedback if data is unavailable or if there’s an error.
Pro5: Weather and NOTAM/TFR fetching are handled in separate functions, making the code easier to maintain and extend.
Pro6: The structure allows for easy addition of more data sources or features (e.g., airport info, runway data).
Con1: The code assumes certain fields (e.g., clouds[0], forecast[0]) always exist, which may not be true for all airports or weather conditions, potentially causing runtime errors.
Con2: Minimal validation (e.g., only checks for empty fields). No feedback for failed database operations or invalid input.
Con3:Only checks for non-empty input, but doesn’t validate if the code is a valid ICAO code (should be 4 letters, etc.).
Con4: OThe output is basic HTML. There’s no loading indicator, no advanced formatting, and no mobile responsiveness.
Con5: All output is in English and uses imperial/metric units as returned by the API, which may not suit all users.
Summary
The project provides basic information about aviation weather reports.
The project provides basic information on aviation weather reports. As long as the APIs you use allow direct requests from the browser, this project can be considered a solely front-end piece. All of the JavaScript logic runs in the browser, and no backend code is involved. It makes direct API calls from the browser to CheckWX and AeroDataBox. Although it has the advantage of simplicity, there are some limitations. For security reasons, the API key may be exposed in the browser's network tab and source code, so it is not suitable for production use. Additionally, some APIs may block requests from the browser due to security concerns. Therefore, adding a backend would reinforce this project since it would hide API keys, bypass CORS restrictions, and allow the addition of features like user authentication and data storage.