Skip to content

Commit 5e5e52f

Browse files
Merge pull request #1 from codercreative/lesson-14
pulling 3 data points from the open meteo apis
2 parents 4b103a4 + 2368cdd commit 5e5e52f

4 files changed

Lines changed: 269 additions & 16 deletions

File tree

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
# Open API App
22

3+
[Open Meteo](https://open-meteo.com)
4+
[Open Meteo Geocoding]("https://open-meteo.com/en/docs/geocoding-api)
5+
36
## Overview
47

8+
- A simple weather app that uses Open Meteo APIs to show real-time weather data based on the user's city input
9+
- The app displays a weather code illustration, temperature, and the city and country names
10+
511
## How It Works
612

13+
The user enters the name of a city, and the app displays:
14+
15+
- A weather code illustration
16+
- The current temperature
17+
- The city and country names
18+
719
## Key Features
20+
21+
- Fetches live weather data using two Open Meteo APIs
22+
- Displays weather condition (via an illustration), temperature and location
23+
- Pulling API data with async/await JavaScript promises as well as helper functions
24+
25+
## Still in Progress
26+
27+
- Complete function that displays illustration based on city's weather code
28+
- Show a default sun illustration when the app loads
29+
- Display an error message if no city is entered or if the input is invalid
30+
- Clear the input field after displaying the city data

index.html

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,60 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<!-- Google Font -->
7+
<link rel="preconnect" href="https://fonts.googleapis.com" />
8+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9+
<link
10+
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&family=Unica+One&display=swap"
11+
rel="stylesheet"
12+
/>
13+
14+
<!-- Font Awesome Content Delivery Network CDNJS -->
15+
<link
16+
rel="stylesheet"
17+
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
18+
/>
19+
20+
<!-- CSS Style Sheet -->
621
<link rel="stylesheet" href="style.css" />
7-
<title>Weather API</title>
22+
<title>Weather App | Open Api Project</title>
823
</head>
924
<body>
25+
<main>
26+
<header>
27+
<h1>What's the weather today?</h1>
28+
<h2>Choose your location</h2>
29+
</header>
30+
<!-- Using form for accessibility and best practices -->
31+
<form class="search-container">
32+
<input
33+
id="city-input"
34+
type="text"
35+
aria-label="Enter city name"
36+
placeholder="Enter city name"
37+
required
38+
/>
39+
<button id="submit-btn" type="submit" aria-label="Search">
40+
<i class="fa-solid fa-magnifying-glass"></i>
41+
</button>
42+
</form>
43+
44+
<!-- Error message in case the user does not input a valid city name -->
45+
46+
<p class="error-msg hidden">Please enter a valid city name</p>
47+
48+
<div class="weather-container">
49+
<div class="weather-icon">
50+
<!-- Font awesome icon to be replaced by my own illustrations based on weather code in JS -->
51+
<i id="weather-code-illustration" class="fa-solid fa-sun"></i>
52+
</div>
53+
<h2 id="temperature"></h2>
54+
<h2 id="city" class="city"></h2>
55+
<h3 id="country"></h3>
56+
</div>
57+
58+
<section class="img-container"></section>
59+
</main>
1060
<script src="script.js"></script>
1161
</body>
1262
</html>

script.js

Lines changed: 90 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,92 @@
11
"use strict";
22

3-
//function...
4-
fetch("https://api.artic.edu/api/v1/artworks")
5-
.then((response) => {
6-
if (!response.ok) {
7-
throw new Error(`Failed with status ${response.status}`);
8-
}
9-
return response.json();
10-
})
11-
.then((data) => {
12-
console.log(data);
13-
})
14-
.catch((error) => {
15-
console.error(error);
16-
});
3+
// DECLARING VARIABLES
4+
const cityInput = document.getElementById("city-input");
5+
const weatherCodeIllustrationEl = document.getElementById(
6+
"weather-code-illustration"
7+
);
8+
const temperatureEl = document.getElementById("temperature");
9+
const cityEl = document.getElementById("city");
10+
const countryEl = document.getElementById("country");
11+
const submitBtn = document.getElementById("submit-btn");
12+
13+
// EVENT LISTENER
14+
submitBtn.addEventListener("click", (e) => {
15+
e.preventDefault();
16+
17+
const lowerCaseTrimmedUserInput = cityInput.value.trim();
18+
const encodedCityInput = encodeURIComponent(lowerCaseTrimmedUserInput);
19+
20+
fetchCoordinatesFromUsersCityName(encodedCityInput);
21+
});
22+
23+
//CALLING APIS WITH ASYNC FUNCTIONS
24+
//Open Meteo Geocoding API: https://open-meteo.com/en/docs/geocoding-api
25+
async function fetchCoordinatesFromUsersCityName(city) {
26+
try {
27+
const response = await fetch(
28+
`https://geocoding-api.open-meteo.com/v1/search?name=${city}`
29+
);
30+
const data = await response.json();
31+
//Usually many cities share the same name - for the purposes of this app, I only want to display the first result from the open meteo API:
32+
const firstResult = data.results[0];
33+
const cityName = firstResult.name;
34+
const countryName = firstResult.country;
35+
const latitude = firstResult.latitude;
36+
const longitude = firstResult.longitude;
37+
fetchTemperatureAndWeathercode(latitude, longitude);
38+
displayCityNameAndCountry(cityName, countryName);
39+
} catch (error) {
40+
console.error("An error occurred - couldn't fetch city data", error);
41+
}
42+
}
43+
44+
// Open Meteo API: https://open-meteo.com/en/docs
45+
async function fetchTemperatureAndWeathercode(latitude, longitude) {
46+
try {
47+
const response = await fetch(
48+
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current_weather=true&temperature_2m&weather_code`
49+
);
50+
const data = await response.json();
51+
const temperature = data.current_weather.temperature;
52+
const weatherCode = data.current_weather.weathercode;
53+
displayWeatherCodeIllustration(weatherCode);
54+
displayTemperature(temperature);
55+
} catch (error) {
56+
console.error("An error occurred", error);
57+
throw error;
58+
}
59+
}
60+
61+
//HELPER FUNCTIONS
62+
function displayCityNameAndCountry(city, country) {
63+
cityEl.textContent = city;
64+
countryEl.textContent = country;
65+
}
66+
67+
function displayTemperature(temperature) {
68+
temperatureEl.textContent = `${temperature}°C`;
69+
}
70+
71+
function displayWeatherCodeIllustration(weathercode) {
72+
console.log(
73+
`Weather Code: ${weathercode} | `,
74+
"logic pending in this function for displaying weather illustrations based on the weather codes in the comments at the bottom of the JS file"
75+
);
76+
}
77+
//Weather codes from Open Meteo API: https://open-meteo.com/en/docs
78+
// WMO Weather interpretation codes (WW)
79+
// Code Description
80+
// 0 Clear sky
81+
// 1, 2, 3 Mainly clear, partly cloudy, and overcast
82+
// 45, 48 Fog and depositing rime fog
83+
// 51, 53, 55 Drizzle: Light, moderate, and dense intensity
84+
// 56, 57 Freezing Drizzle: Light and dense intensity
85+
// 61, 63, 65 Rain: Slight, moderate and heavy intensity
86+
// 66, 67 Freezing Rain: Light and heavy intensity
87+
// 71, 73, 75 Snow fall: Slight, moderate, and heavy intensity
88+
// 77 Snow grains
89+
// 80, 81, 82 Rain showers: Slight, moderate, and violent
90+
// 85, 86 Snow showers slight and heavy
91+
// 95 * Thunderstorm: Slight or moderate
92+
// 96, 99 * Thunderstorm with slight and heavy hail

style.css

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,107 @@
1+
/* ------
2+
GENERAL STYLES
3+
------*/
4+
5+
* {
6+
box-sizing: border-box;
7+
margin: 0;
8+
padding: 0;
9+
}
10+
11+
html {
12+
font-family: "Unica One", sans-serif;
13+
}
14+
115
body {
2-
background-color: goldenrod;
16+
background: linear-gradient(145deg, #fff085, #feba17);
17+
}
18+
19+
main {
20+
margin: 0 auto;
21+
max-width: 450px;
22+
height: 100vh;
23+
width: 90%;
24+
display: flex;
25+
flex-direction: column;
26+
align-items: center;
27+
padding-top: 6em;
28+
}
29+
30+
header {
31+
margin-bottom: 0.5em;
32+
}
33+
34+
h1,
35+
h2,
36+
h3,
37+
p {
38+
text-align: center;
39+
}
40+
41+
h1 {
42+
font-size: 2.2rem;
43+
margin-bottom: 1.5em;
44+
}
45+
46+
h2 {
47+
font-size: 2rem;
48+
}
49+
50+
h3 {
51+
font-size: 1.5rem;
52+
}
53+
54+
/* ------
55+
INPUT FORM FOR USER TO INPUT CITY NAME
56+
------*/
57+
58+
.search-container {
59+
display: flex;
60+
gap: 8px;
61+
margin: 1.5em 0;
62+
}
63+
64+
.search-container input {
65+
font-family: "Roboto", sans-serif;
66+
font-size: 1.2rem;
67+
border-radius: 24px;
68+
padding: 5px 10px;
69+
border: none;
70+
width: 100%;
71+
}
72+
73+
.search-container button {
74+
border: none;
75+
background-color: transparent;
76+
font-size: 1.2rem;
77+
cursor: pointer;
78+
}
79+
80+
/* ------
81+
SECTION FOR DISPLAYING THE CITY'S WEATHER CODE (IN AN ILLUSTRATION), TEMPERATURE AND CITY NAME
82+
------*/
83+
84+
.weather-container {
85+
margin-top: 2em;
86+
display: flex;
87+
flex-direction: column;
88+
align-items: center;
89+
gap: 1em;
90+
}
91+
92+
.weather-container .fa-sun {
93+
font-size: 2rem;
94+
}
95+
96+
/* ------
97+
ERROR MESSAGE IF USER DOES NOT ENTER A VALID CITY NAME
98+
------*/
99+
100+
.error-msg {
101+
font-family: "Roboto", sans-serif;
102+
color: #ff0000;
103+
}
104+
105+
.hidden {
106+
display: none;
3107
}

0 commit comments

Comments
 (0)