Skip to content
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

Tigist/zoisite #58

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@ Great weather apps do these two things:
1. Pull weather data from a data source
1. Display the weather in readable, compelling way

![DuckDuckGo's weather modal, which features city name, temperature reading, and the weather. Some icons show sunny weather, some icons show rainy weather, and some show cloudy weather.](ada-project-docs/assets/example-duckduckgo.png)
![DuckDuckGo's weather modal, which features city name, temperature reading, and the weather. Some icons show sunny weather, some icons show rainy weather, and some show cloudy weather.](ada-project-docs/assets/example-duckduckgo.png)
_Fig. DuckDuckGo's weather modal, which features city name, temperature reading, and weather icons._

Our goal is to create a fun, small weather app that focuses on displaying the weather.

Our weather app will set the weather using user interaction and get the weather from a 3rd party API, OpenWeather.

![Example weather app: The temperature reads 62, in yellow text. The selected dropdown for "Sky" is "Cloudy." There is a depiction of cloudy weather. The city name is "Hoboken." The header reads "Hoboken."](ada-project-docs/assets/cloudy-62.png)
![Example weather app: The temperature reads 62, in yellow text. The selected dropdown for "Sky" is "Cloudy." There is a depiction of cloudy weather. The city name is "Hoboken." The header reads "Hoboken."](ada-project-docs/assets/cloudy-62.png)
_Fig. Example weather app displaying the weather for Hoboken._

![Example weather app: The temperature reads 85, in red text. The selected dropdown for "Sky" is "Sunny." There is a depiction of sunny weather. The city name is "Santo Domingo" The header reads "Santo Domingo."](ada-project-docs/assets/santo-domingo-85.png)
![Example weather app: The temperature reads 85, in red text. The selected dropdown for "Sky" is "Sunny." There is a depiction of sunny weather. The city name is "Santo Domingo" The header reads "Santo Domingo."](ada-project-docs/assets/santo-domingo-85.png)
_Fig. Example weather app displaying the weather for Santo Domingo._

![Example weather app: The temperature reads 38, in teal text. The selected dropdown for "Sky" is "Snowy." There is a depiction of snowy weather. The city name is "Bozeman." The header reads "Bozeman."](ada-project-docs/assets/snow-38.png)
![Example weather app: The temperature reads 38, in teal text. The selected dropdown for "Sky" is "Snowy." There is a depiction of snowy weather. The city name is "Bozeman." The header reads "Bozeman."](ada-project-docs/assets/snow-38.png)
_Fig. Example weather app displaying the weather for Bozeman._

![Example weather app: The temperature reads 49, in teal text. The selected dropdown for "Sky" is "Rainy." There is a depiction of rainy weather. The city name is "Seattle." The header reads "Seattle."](ada-project-docs/assets/rainy-49.png)
![Example weather app: The temperature reads 49, in teal text. The selected dropdown for "Sky" is "Rainy." There is a depiction of rainy weather. The city name is "Seattle." The header reads "Seattle."](ada-project-docs/assets/rainy-49.png)
_Fig. Example weather app displaying the weather for Seattle._

## How to Complete and Submit
Expand Down Expand Up @@ -75,9 +75,9 @@ This should be done during the Wave 1 initial setup of your `index.html` page.

## Content Requirements

For this project, there are no requirements around color schemes, font choices, or layouts.
For this project, there are no requirements around color schemes, font choices, or layouts.

Note that applying styles with CSS is one of many learning goals of this project -- it is not the central learning goal. You may enjoy being creative with styles, but we encourage you to not concern yourself with getting the styles perfect. Remember, you can always choose to continue working on styling after you've completed all functional requirements.
Note that applying styles with CSS is one of many learning goals of this project -- it is not the central learning goal. You may enjoy being creative with styles, but we encourage you to not concern yourself with getting the styles perfect. Remember, you can always choose to continue working on styling after you've completed all functional requirements.

However, _at a minimum_, your project must contain these elements:

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sky/daoudi-aissa-Pe1Ol9oLc4o-unsplash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sky/kyaw-zay-ya-8vHAfhWoqEQ-unsplash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 53 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,64 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Weather Report</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Rubik&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Rubik&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="styles/index.css" />
</head>

<body>
<main>
<div id="top">
<h1>Weather Report</h1>
</div>
<div id="buttom">
<div id="buttom--left">
<div id="buttom--left--temp">
<div id="temp--title">Temp</div>
<div id="temp--controls">
<button id="decrease-t">down</button>
<div id="temperature">70</div>
<button id="increase-t">up</button>
Comment on lines +22 to +26

Choose a reason for hiding this comment

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

Prefer that these elements be nested in a semantic html element, maybe something like a section tag. Additionally, I think that the "temp" and "70" text should be heading tags or something more semantic than just a div tag, which has no meaning but is often used for styling.

</div>
</div>
<div id="buttom--left--sky">
<div id="sky--title">Sky</div>

Choose a reason for hiding this comment

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

Prefer "Sky" text to be a heading tag or something more semantic than a div.

Also "Sky" element and the select element with options elements could all be contained in a section tag to bring more structure to the HTML. Someone not navigating your site visually (maybe using a screen reader) would understand that "Sky" and the drop down menu are grouped together.

<div id="sky--controls">
<select name="sky-options" id="sky--options">
<option value="rainy">Rainy</option>
<option value="sunny">Sunny</option>
<option value="snowy">Snowy</option>
<option value="cloudy">Cloudy</option>
</select>
</div>
</div>
<div id="buttom-left--city">
<div id="city--title">City</div>

Choose a reason for hiding this comment

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

Prefer heading tag for "City" text

<div id="city--controls">
<form action="/url" method="GET">
<input id="city-input" type="text" name="city_name" placeholder="Please enter your city" required />
<button id="submit-button" type="submit">Submit</button>
</form>
<div id="reset-button">
<input type="reset" value="Reset" />
</div>
Comment on lines +43 to +49

Choose a reason for hiding this comment

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

The form, buttons and the "City" heading should all be grouped together with an element like a section element to convey to users that these elements are logically grouped together.

</div>
</div>
</div>
<div id="buttom--right">
<div id="city-display">
<div id="city-display--name">Current City</div>

Choose a reason for hiding this comment

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

Use heading tag

</div>
</div>
</div>
</main>
<script src="./src/index.js"></script>
<script src="./node_modules/axios/dist/axios.min.js"></script>
</body>

</html>
151 changes: 151 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
const state = {
currentTemp: 70,
backgroundColor: document.getElementById('buttom--left'),
landscapeImg: document.getElementById('buttom--right'),
cityInput: document.getElementById('city-input'),
location: null,
lat: null,
lon: null,
skyCondition: document.getElementById('sky--options'),

Choose a reason for hiding this comment

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

Name variables to describe what the element is without needing to go refer back to HTML. Something like skyConditionMenu could work here

skyImg: document.getElementById('top')
}
// changes the temp on the page
const changesTempDisplay = () => {
const tempControl = document.getElementById('temperature');
tempControl.textContent = `${state.currentTemp}`
}
// CHANGES TEMP
const increaseTemp = () => {
state.currentTemp++;
changesTempDisplay()
};

const decreaseTemp = () => {
state.currentTemp--;
changesTempDisplay()
};
Comment on lines +18 to +26

Choose a reason for hiding this comment

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

notice that these two methods do essentially the same thing but the difference is ++ or --.

How could you combine the logic of these two methods into one event handler called handleTempChange()?

What if you pass in the event object as an argument and you check if the event's target has an id increase-t or decrease-t and depending on the id then you could ++ or --

const handleTempChange = (event) => {
    if (event.target.id === 'increase-t') {
        state.currentTemp++;
    } else {
        state.currentTemp--;
    }
    changesTempDisplay();
};


// sky background change with sky option
const skyBackground = () => {
console.log('skyBackground')
const condition = state.skyCondition.value
if(condition == 'sunny') {
console.log('sunny')

Choose a reason for hiding this comment

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

Remove the debugging print statements on line 30 and 33 before you open a pull request for your code to be reviewed

state.skyImg.style.backgroundImage = 'url(assets/sky/kyaw-zay-ya-8vHAfhWoqEQ-unsplash.jpg)';
} else if(condition == 'rainy') {
state.skyImg.style.backgroundImage = 'url(assets/sky/eutah-mizushima-F-t5EpfQNpk-unsplash.jpg)';
} else if(condition == 'snowy'){
state.skyImg.style.backgroundImage = 'url(assets/sky/fabrizio-conti-Mbm0WnJ5emc-unsplash.jpg)';
} else if(condition == 'cloudy') {
state.skyImg.style.backgroundImage = 'url(assets/sky/daoudi-aissa-Pe1Ol9oLc4o-unsplash.jpg)';
Comment on lines +34 to +40

Choose a reason for hiding this comment

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

Prefer that the paths for each picture be referenced by constant variables which would keep this code more concise. It's also just good practice to reference strings with descriptive variable names.

const CLOUDY_IMG = url(assets/sky/daoudi-aissa-Pe1Ol9oLc4o-unsplash.jpg)';
state.skyImg.style.backgroundImage = CLOUDY_IMG;

}

}

Choose a reason for hiding this comment

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

Nitpick - indentation is off, line 43 should be unindented one level to the left


// CHANGE BACKGROND COLOR AND IMAGE WITH TEMP CHANGE
const changeBackgrounds = () => {
if (state.currentTemp >= 80) {
state.backgroundColor.style.backgroundColor = 'red';
state.landscapeImg.style.backgroundImage = 'url(assets/landscape/cody-doherty-AeqlmVWtzFA-unsplash.jpg)';
} else if (state.currentTemp >= 70) {
state.backgroundColor.style.backgroundColor = 'orange';
state.landscapeImg.style.backgroundImage = 'url(assets/landscape/alexandr-hovhannisyan-RkOtjbPuHZw-unsplash.jpg)';
} else if (state.currentTemp >= 60) {
state.backgroundColor.style.backgroundColor = 'yellow';
state.landscapeImg.style.backgroundImage = 'url(assets/landscape/andrew-neel-a_K7R1kugUE-unsplash.jpg)';
} else if (state.currentTemp >= 50) {
state.backgroundColor.style.backgroundColor = 'green';
state.landscapeImg.style.backgroundImage = 'url(assets/landscape/joel-jasmin-forestbird-4S3iMBIappo-unsplash.jpg)';
} else {
state.backgroundColor.style.backgroundColor = 'teal';
}
}

Choose a reason for hiding this comment

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

Another way to format this method would be to have an object that has temp values as keys and then you could have values be a list and the list could hold background color and background image, like:

const 80_DEGREE_IMG = 'url(assets/landscape/cody-doherty-AeqlmVWtzFA-unsplash.jpg)';
const 70_DEGREE_IMG = 'url(assets/landscape/alexandr-hovhannisyan-RkOtjbPuHZw-unsplash.jpg)';

const tempDisplayObject = {80: ['red',  80_DEGREE_IMG], 70: ['orange', 70_DEGREE_IMG]} 

When you have an object, you don't need to do if/else if/else if/ else which can introduce bugs and also adds complexity to the method. If you have an object, than you can iterate over the object and check the keys with state.currentTemp and then get the correct values to set backgroundColor and backgroundImage


// DISPLAY CITY CHANGES ON INPUT
const updateCity = () => {
document.getElementById('city-display--name').textContent = state.cityInput.value
}

// reset city
const resetCity = () => {
state.cityInput.value = "";
updateCity();
}

// calling API
// Convert from Kel to Fahren
const handleRealTemp = async (kelvin) => {

Choose a reason for hiding this comment

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

Do we need the async keyword here? I don't see a corresponding await.

This method converts kelvin to Fahrenheit and then calls changeTempDisplay() which is not an async method itself.

state.currentTemp = Math.floor((kelvin - 273.15) * 9/5 + 32 );
changesTempDisplay()
};

// activated by submit button
const submitLocationInput = () => {
state.location = state.cityInput.value;
getLatLon();
}

// API CALLS
// loaction api
const getLatLon = () => {

Choose a reason for hiding this comment

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

This comment applies to both methods that make an asynchronous API call:

Usually a pattern when using promises is to return the promise chain like:

return axios
    .get(someUrl)
    .then()
    .catch()

You've used promises in a way that you call other helper methods in your .then block so the functionality of your project works as expected even though you don't return the promise chain (see lines 91 and 110). There may be times when you aren't able to call other helper methods in .then() and you will need to return the promise chain so I wanted to call this to your attention.

See slide 15 from our "Calling APIs" presentation for ore details.

axios.get('http://127.0.0.1:5000/location', {

Choose a reason for hiding this comment

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

Prefer to put the URL in a constant variable

Maybe something like BASE_URL = http://127.0.0.1:5000;

Then on line 91, you can call:

axios.get(`${BASE_URL}/location`)

params: {
q: state.location,
},
})
.then((response) => {
state.lon = response.data[0].lon;
state.lat = response.data[0].lat;
})
.then(() => {
getWeather()
})
.catch((error) => {
console.log(error)
})
}

// weather api call
const getWeather = () => {
axios.get('http://127.0.0.1:5000/weather', {

Choose a reason for hiding this comment

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

Prefer to have URL stored in a constant variable

params: {
lat: state.lat,
lon: state.lon,
},
})
.then((response) => {
kelvin = response.data.main.temp;
handleRealTemp(kelvin);
})
.then(() => {
changeBackgrounds()

Choose a reason for hiding this comment

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

Could you call changeBackgrounds in the then above this block? Like,

 .then((response) => {
        kelvin = response.data.main.temp;
        handleRealTemp(kelvin);
        changeBackgrounds()
    })    
    .catch((error) =>{
        console.log(error)
    })
// and delete lines 120-122

})
.catch((error) =>{
console.log(error)
})
}

// REGISTER EVENT LISTENER
const registerEventHandler = () => {
const tempDecrease = document.getElementById('decrease-t');

Choose a reason for hiding this comment

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

I can't tell from the name of the variable or the selector used what kind of element tempDecrease is without going to look at the HTML. Consider renaming the variable to describe what the element is like tempDecreaseButton.

Also, in your state object has a couple of key-value pairs that are elements. Could you also add the elements in registerEventHandler into the state object? Right now you have some elements in object and some elements defined in a method, it would be nice to put them all in one place to keep the code consistent and organized.

If you add your elements in the state object then you can delete line 130 and then directly access the element on line 131 like:
state.tempDecreaseButton.addEventListener('click', decreaseTemp);

tempDecrease.addEventListener('click', decreaseTemp);
tempDecrease.addEventListener('click', changeBackgrounds);

const tempIncrease = document.getElementById('increase-t');

Choose a reason for hiding this comment

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

Same comment as above, consider renaming this variable to tempIncreaseButton and adding it to state object

Would be good to add all the elements in registerEventHandler in the state object.

tempIncrease.addEventListener('click', increaseTemp);
tempIncrease.addEventListener('click', changeBackgrounds);

const inputCity = document.getElementById('city-input');
inputCity.addEventListener('keyup', updateCity);

const submitButton = document.getElementById('submit-button');
submitButton.addEventListener('click', submitLocationInput);

state.skyCondition.addEventListener('change', skyBackground);

const resetButton = document.getElementById('reset-button');
resetButton.addEventListener('click', resetCity);

}

document.addEventListener('DOMContentLoaded', registerEventHandler)
Loading