-
Notifications
You must be signed in to change notification settings - Fork 220
EFM - API Weather App #233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| config.js |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <link rel="stylesheet" href="style.css" /> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>Weather-App</title> | ||
| <link | ||
| href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" | ||
| rel="stylesheet" | ||
| integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" | ||
| crossorigin="anonymous" | ||
| /> | ||
| <link | ||
| rel="stylesheet" | ||
| href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" | ||
| /> | ||
| </head> | ||
| <body> | ||
| <div class="container py-5"> | ||
| <!-- Search Row --> | ||
| <div class="row"> | ||
| <div class="col-lg-7 mx-auto text-center"> | ||
| <h1>Weather Project</h1> | ||
| <hr /> | ||
| </div> | ||
|
|
||
| <div class="col-lg-7 mx-auto pt-5"> | ||
| <form class="search-form d-flex mb-5"> | ||
| <input | ||
| type="text" | ||
| id="search-location" | ||
| class="form-control me-3" | ||
| placeholder="Type City Here" | ||
| /> | ||
| <button type="button" class="btn btn-primary search">Search</button> | ||
| </form> | ||
| </div> | ||
|
|
||
| <!-- Local Weather Row --> | ||
| <div class="row city-weather"> | ||
| <!-- append city weather here --> | ||
| </div> | ||
|
|
||
| <!-- 5 days Forecast Row --> | ||
| <div class="row forecast-weather mt-5"> | ||
| <!-- append 5 day forecast here --> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <script src="config.js"></script> | ||
| <script src="main.js"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,156 @@ | ||||||||||
| // API WEATHER APP | ||||||||||
| // Weather array to hold info from API | ||||||||||
| let cityWeather = []; | ||||||||||
| let forecastWeather = []; | ||||||||||
|
|
||||||||||
| // Event Listener added to the Search Button | ||||||||||
| document.querySelector(".search").addEventListener("click", function (e) { | ||||||||||
| e.preventDefault(); | ||||||||||
| const searchLocation = document.querySelector("#search-location").value; | ||||||||||
|
|
||||||||||
| // document.querySelector("#search-location").value = ""; | ||||||||||
| fetchGeoLocationData(searchLocation); | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| // Function that grabs the coordinates to be used later by fetchWeather to generate weather data | ||||||||||
| const fetchGeoLocationData = (searchLocation) => { | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good argument name |
||||||||||
| const geolocationURL = `https://api.openweathermap.org/geo/1.0/direct?q=${searchLocation}&appid=${apiKey}`; | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good you didn't commit your API but it should have been as an environment variable, its crashing your app. |
||||||||||
|
|
||||||||||
| fetch(geolocationURL, { | ||||||||||
| method: "GET", | ||||||||||
| dataType: "json", | ||||||||||
| }) | ||||||||||
| .then((res) => res.json()) | ||||||||||
| .then((data) => { | ||||||||||
|
Comment on lines
+23
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. be more clear with the argument naming.
Suggested change
|
||||||||||
| let lat = data[0].lat; | ||||||||||
| let lon = data[0].lon; | ||||||||||
|
Comment on lines
+25
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why let? |
||||||||||
| fetchCurrentWeather(lat, lon); | ||||||||||
| fetchForecastWeather(lat, lon); | ||||||||||
| }); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| // Func that takes lat and lon to plug into URL to fetch current weather data | ||||||||||
| const fetchCurrentWeather = (lat, lon) => { | ||||||||||
| const weatherURL = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}`; | ||||||||||
| fetch(weatherURL, { | ||||||||||
| method: "GET", | ||||||||||
| dataType: "json", | ||||||||||
| }) | ||||||||||
| .then((res) => res.json()) | ||||||||||
| .then((data) => addWeatherData(data)); | ||||||||||
| // .then((data) => console.log(data)); | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not commit commented code |
||||||||||
| }; | ||||||||||
|
|
||||||||||
| // Func that fetches forecast weather data (directly in F) | ||||||||||
| const fetchForecastWeather = (lat, lon) => { | ||||||||||
| const forecastURL = `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&appid=${apiKey}&units=imperial`; | ||||||||||
| fetch(forecastURL, { | ||||||||||
| method: "GET", | ||||||||||
| dataType: "json", | ||||||||||
| }) | ||||||||||
| .then((res) => res.json()) | ||||||||||
| // .then((data) => console.log(data.list)); | ||||||||||
| .then((forecastData) => addForecastData(forecastData)); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| // Convert Kelvin to Fahrenheit | ||||||||||
| const convertKelvinToFahrenheit = (kelvin) => { | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrong argument and function name. Be more precise.
Suggested change
|
||||||||||
| return Math.round(1.8 * (kelvin - 273) + 32); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| // Func to create weather obj to update the global weather array | ||||||||||
| function addWeatherData(data) { | ||||||||||
| cityWeather = []; | ||||||||||
|
|
||||||||||
| const weatherObj = { | ||||||||||
| temp: convertKelvinToFahrenheit(data.main.temp), | ||||||||||
| name: data.name, | ||||||||||
| condition: data.weather[0].main, | ||||||||||
| icon: data.weather[0].icon, | ||||||||||
|
Comment on lines
+66
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all of these will crash if data is undefined. Your code will fail compile and silently crash to the user. |
||||||||||
| }; | ||||||||||
| cityWeather.push(weatherObj); | ||||||||||
| // console.log(cityWeather); | ||||||||||
| renderCurrentWeather(cityWeather); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| function renderCurrentWeather(arr) { | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. arr is a very bad argument name. |
||||||||||
| const weatherContainer = document.querySelector(".city-weather"); | ||||||||||
| document.querySelector(".city-weather").replaceChildren(); | ||||||||||
|
|
||||||||||
| for (let i = 0; i < arr.length; i++) { | ||||||||||
| const cityWeatherData = arr[i]; | ||||||||||
|
|
||||||||||
| const template = ` | ||||||||||
| <div class="col-12 d-flex justify-content-center"> | ||||||||||
| <div class="row align-items-center w-75"> | ||||||||||
| <div class="col-md-6 text-center"> | ||||||||||
| <div class="fs-3 fw-semibold">${cityWeatherData.temp}F°</div> | ||||||||||
| <h2 class="fw-bold">${cityWeatherData.name}</h2> | ||||||||||
| <p class="fs-4 mb-0">${cityWeatherData.condition}</p> | ||||||||||
| </div> | ||||||||||
| <div class="col-md-6 text-center"> | ||||||||||
| <img | ||||||||||
| src="https://openweathermap.org/img/wn/${cityWeatherData.icon}@2x.png" | ||||||||||
| class="img-fluid"> | ||||||||||
| </div> | ||||||||||
| </div> | ||||||||||
| </div> | ||||||||||
| `; | ||||||||||
|
|
||||||||||
| weatherContainer.insertAdjacentHTML("afterbegin", template); | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // Func to convert dt_txt into week days with the JS Intl Obj | ||||||||||
| const getWeekDay = (dateString) => { | ||||||||||
| const date = new Date(dateString); | ||||||||||
|
|
||||||||||
| return new Intl.DateTimeFormat("en-US", { | ||||||||||
| weekday: "long", | ||||||||||
| }).format(date); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| // Func to create forecast weather array | ||||||||||
| function addForecastData(forecastData) { | ||||||||||
| forecastWeather = []; | ||||||||||
| let usedDates = []; | ||||||||||
|
|
||||||||||
| forecastData.list.forEach(function (item) { | ||||||||||
| // console.log(item.dt_txt); | ||||||||||
| let date = item.dt_txt.split(" ")[0]; | ||||||||||
| console.log(date); | ||||||||||
| if (forecastWeather.length === 5) return; | ||||||||||
| if (!usedDates.includes(date)) { | ||||||||||
| usedDates.push(date); | ||||||||||
|
|
||||||||||
| const forecastObj = { | ||||||||||
| condition: item.weather[0].main, | ||||||||||
| temp: item.main.temp, | ||||||||||
| icon: item.weather[0].icon, | ||||||||||
| day: getWeekDay(date), | ||||||||||
| }; | ||||||||||
| forecastWeather.push(forecastObj); | ||||||||||
| // console.log(forecastWeather); | ||||||||||
| } | ||||||||||
| }); | ||||||||||
| renderForecastWeather(forecastWeather); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| function renderForecastWeather(arr) { | ||||||||||
| const forecastContainer = document.querySelector(".forecast-weather"); | ||||||||||
| document.querySelector(".forecast-weather").replaceChildren(); | ||||||||||
|
|
||||||||||
| for (let i = 0; i < arr.length; i++) { | ||||||||||
| const forecastWeatherData = arr[i]; | ||||||||||
|
|
||||||||||
| const template = ` | ||||||||||
| <div class="col-md-2 text-center border"> | ||||||||||
| <div class="fs-3 fw-semibold">${forecastWeatherData.condition}°</div> | ||||||||||
| <h2 class="fw-bold">${Math.round(forecastWeatherData.temp)}</h2> | ||||||||||
| <div><img src="https://openweathermap.org/img/wn/${forecastWeatherData.icon}@2x.png" | ||||||||||
| class="img-fluid"></img></div> | ||||||||||
| <div class="fs-5 fw-semibold">${forecastWeatherData.day}</div>`; | ||||||||||
|
|
||||||||||
| forecastContainer.insertAdjacentHTML("beforeend", template); | ||||||||||
| } | ||||||||||
| } | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be const.