Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config.js
54 changes: 54 additions & 0 deletions index.html
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>
156 changes: 156 additions & 0 deletions main.js
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 = [];
Comment on lines +3 to +4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be const.


// 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) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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}`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

be more clear with the argument naming.

Suggested change
.then((res) => res.json())
.then((data) => {
.then((serverData) => serverData.json())
.then((parsedData) => {

let lat = data[0].lat;
let lon = data[0].lon;
Comment on lines +25 to +26
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong argument and function name. Be more precise.

Suggested change
const convertKelvinToFahrenheit = (kelvin) => {
const convertTemperatureFromKelvinToFahrenheit = (kelvinTemperature) => {

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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.
Use ? to avoid this and handle error

};
cityWeather.push(weatherObj);
// console.log(cityWeather);
renderCurrentWeather(cityWeather);
}

function renderCurrentWeather(arr) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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);
}
}
Empty file added style.css
Empty file.