Last active
May 16, 2019 17:28
-
-
Save iamsainikhil/c82a9ee37afa4169602579f5c9271346 to your computer and use it in GitHub Desktop.
A Robust Weather App using JavaScript by Sai Nikhil | CodePen -> https://codepen.io/iamsainikhil/pen/BqNzbM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>A Robust Weather App using JavaScript by Sai Nikhil</title> | |
<link href="https://fonts.googleapis.com/css?family=Space+Mono" rel="stylesheet"> | |
<style> | |
#app { | |
display: flex; | |
flex-direction: row wrap; | |
justify-content: flex-start; | |
font-family: 'Space Mono', monospace; | |
} | |
.card { | |
border: 1px solid #808080; | |
padding: 0 20px 20px 20px; | |
} | |
.card img { | |
margin-top: -10px; | |
margin-bottom: -20px; | |
margin-left: -5px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"></div> | |
<script> | |
// parameters | |
let city = ''; | |
let lat = 38.9311; | |
let long = -77.3489; | |
let zipCode = ''; | |
let countryCode = ''; | |
const imgPath = 'https://openweathermap.org/img/w/'; | |
const appId = '1fc8f4cbcea758f39c307dffd62a5418'; | |
const apiUrl = 'https://api.openweathermap.org/data/2.5/weather?'; | |
// html body | |
const app = document.getElementById('app'); | |
const div = document.createElement('div'); | |
const cityElement = document.createElement('h2'); | |
const tempElement = document.createElement('p'); | |
const weatherElement = document.createElement('p'); | |
const discElement = document.createElement('span'); | |
const image = document.createElement('img'); | |
const error = document.createElement('p'); | |
div.appendChild(error); | |
div.appendChild(cityElement); | |
div.appendChild(tempElement); | |
div.appendChild(weatherElement); | |
div.appendChild(image); | |
div.appendChild(discElement); | |
app.appendChild(div); | |
// display temperature | |
function getTemperature(temperature) { | |
const c = Math.round(temperature - 273.15); | |
const f = Math.round((temperature - 273.15) * 9 / 5 + 32); | |
tempElement.innerHTML = `Temperature: <b>${c}°C</b>`; | |
} | |
// display weather icon | |
function displayIcon(code) { | |
image.src = `${imgPath}${code}.png`; | |
} | |
// display error message | |
function displayError(err) { | |
error.innerHTML = `😥 ${err}`; | |
error.style.textTransform = 'capitalize'; | |
error.style.display = 'block'; | |
error.style.color = ' #DC143C'; | |
} | |
// set html elements | |
function displayElements(res) { | |
error.style.display = 'none'; | |
cityElement.textContent = res.name; | |
weatherElement.innerHTML = `Weather: <b>${res.weather[0].main}</b>`; | |
discElement.textContent = res.weather[0].description; | |
getTemperature(res.main.temp); | |
displayIcon(res.weather[0].icon); | |
div.setAttribute('class', 'card'); | |
} | |
// fetch weather data | |
function getWeather(type = 'old') { | |
// get position | |
if ("geolocation" in navigator) { | |
// check if geolocation is supported/enabled on current browser | |
navigator.geolocation.getCurrentPosition( | |
function success(position) { | |
// for when getting location is a success | |
lat = position.coords.latitude; | |
long = position.coords.longitude; | |
const weatherByPosition = `${apiUrl}lat=${lat}&lon=${long}&appid=${appId}`; | |
// fetch weather data by position | |
fetchData(type, weatherByPosition) | |
}, | |
function error(error_message) { | |
// for when getting location results in an error | |
console.error('An error has occured while retrieving location', error_message); | |
// use ip-api | |
const http = new XMLHttpRequest(); | |
http.open('GET', 'https://ipapi.co/json'); | |
http.send(); | |
http.onreadystatechange = function() { | |
if (this.readyState === 4 && this.status === 200) { | |
let response = JSON.parse(http.responseText); | |
console.log('IP Data', response); | |
city = response.city; | |
lat = response.latitude; | |
long = response.longitude; | |
zipCode = response.postal; | |
countryCode = response.country; | |
// sometimes there won't be a city if using proxy ip or vpn | |
if (response.city === '') { | |
const weatherByPosition = `${apiUrl}lat=${lat}&lon=${long}&appid=${appId}`; | |
// fetch weather data by position | |
fetchData(type, weatherByPosition) | |
} else { | |
const weatherByCity = `${apiUrl}q=${city}&appid=${appId}`; | |
// fetch weather data by city | |
fetchData(type, weatherByCity) | |
} | |
} else if (status !== 200){ | |
displayError(`${this.status} Error`); | |
} | |
} | |
} | |
); | |
} else { | |
// geolocation is not supported | |
// get your location some other way | |
alert('geolocation is not enabled on this browser'); | |
} | |
} | |
function fetchData(type, url) { | |
if (type === 'new') { | |
// ES6 | |
fetch(url) | |
.then(data => {return data.json();}) | |
.then(res => { | |
console.log('Weather Data', res); | |
// if response code is 404 | |
if (res.cod === '404') { | |
displayError(res.message); | |
// get weather by postal code & country code | |
const weatherByCodes = `${apiUrl}zip=${zipCode},${countryCode}&appid=${appId}`; | |
fetchData(type, url = weatherByCodes); | |
} | |
displayElements(res); | |
}) | |
.catch(err => { | |
displayError(err); | |
console.log(err); | |
}); | |
} else { | |
// older version | |
const http = new XMLHttpRequest(); | |
http.open('GET', url); | |
http.send(); | |
http.onreadystatechange = function() { | |
if (this.readyState === 4 && this.status === 200) { | |
let response = JSON.parse(http.responseText); | |
console.log('Weather Data', response); | |
displayElements(response); | |
} else if (status !== 200){ | |
displayError(`${this.status} Error`); | |
} | |
} | |
} | |
} | |
// perform request | |
window.onload = getWeather(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// parameters | |
let city = ''; | |
let lat = 38.9311; | |
let long = -77.3489; | |
let zipCode = ''; | |
let countryCode = ''; | |
const imgPath = 'https://openweathermap.org/img/w/'; | |
const appId = '1fc8f4cbcea758f39c307dffd62a5418'; | |
const apiUrl = 'https://api.openweathermap.org/data/2.5/weather?'; | |
// html body | |
const app = document.getElementById('app'); | |
const div = document.createElement('div'); | |
const cityElement = document.createElement('h2'); | |
const tempElement = document.createElement('p'); | |
const weatherElement = document.createElement('p'); | |
const discElement = document.createElement('span'); | |
const image = document.createElement('img'); | |
const error = document.createElement('p'); | |
div.appendChild(error); | |
div.appendChild(cityElement); | |
div.appendChild(tempElement); | |
div.appendChild(weatherElement); | |
div.appendChild(image); | |
div.appendChild(discElement); | |
app.appendChild(div); | |
// display temperature | |
function getTemperature(temperature) { | |
const c = Math.round(temperature - 273.15); | |
const f = Math.round((temperature - 273.15) * 9 / 5 + 32); | |
tempElement.innerHTML = `Temperature: <b>${c}°C</b>`; | |
} | |
// display weather icon | |
function displayIcon(code) { | |
image.src = `${imgPath}${code}.png`; | |
} | |
// display error message | |
function displayError(err) { | |
error.innerHTML = `😥 ${err}`; | |
error.style.textTransform = 'capitalize'; | |
error.style.display = 'block'; | |
error.style.color = ' #DC143C'; | |
} | |
// set html elements | |
function displayElements(res) { | |
error.style.display = 'none'; | |
cityElement.textContent = res.name; | |
weatherElement.innerHTML = `Weather: <b>${res.weather[0].main}</b>`; | |
discElement.textContent = res.weather[0].description; | |
getTemperature(res.main.temp); | |
displayIcon(res.weather[0].icon); | |
div.setAttribute('class', 'card'); | |
} | |
// fetch weather data | |
function getWeather(type = 'old') { | |
// get position | |
if ("geolocation" in navigator) { | |
// check if geolocation is supported/enabled on current browser | |
navigator.geolocation.getCurrentPosition( | |
function success(position) { | |
// for when getting location is a success | |
lat = position.coords.latitude; | |
long = position.coords.longitude; | |
const weatherByPosition = `${apiUrl}lat=${lat}&lon=${long}&appid=${appId}`; | |
// fetch weather data by position | |
fetchData(type, weatherByPosition) | |
}, | |
function error(error_message) { | |
// for when getting location results in an error | |
console.error('An error has occured while retrieving location', error_message); | |
// use ip-api | |
const http = new XMLHttpRequest(); | |
http.open('GET', 'https://ipapi.co/json'); | |
http.send(); | |
http.onreadystatechange = function() { | |
if (this.readyState === 4 && this.status === 200) { | |
let response = JSON.parse(http.responseText); | |
console.log('IP Data', response); | |
city = response.city; | |
lat = response.latitude; | |
long = response.longitude; | |
zipCode = response.postal; | |
countryCode = response.country; | |
// sometimes there won't be a city if using proxy ip or vpn | |
if (response.city === '') { | |
const weatherByPosition = `${apiUrl}lat=${lat}&lon=${long}&appid=${appId}`; | |
// fetch weather data by position | |
fetchData(type, weatherByPosition) | |
} else { | |
const weatherByCity = `${apiUrl}q=${city}&appid=${appId}`; | |
// fetch weather data by city | |
fetchData(type, weatherByCity) | |
} | |
} else if (status !== 200){ | |
displayError(`${this.status} Error`); | |
} | |
} | |
} | |
); | |
} else { | |
// geolocation is not supported | |
// get your location some other way | |
alert('geolocation is not enabled on this browser'); | |
} | |
} | |
function fetchData(type, url) { | |
if (type === 'new') { | |
// ES6 | |
fetch(url) | |
.then(data => {return data.json();}) | |
.then(res => { | |
console.log('Weather Data', res); | |
// if response code is 404 | |
if (res.cod === '404') { | |
displayError(res.message); | |
// get weather by postal code & country code | |
const weatherByCodes = `${apiUrl}zip=${zipCode},${countryCode}&appid=${appId}`; | |
fetchData(type, url = weatherByCodes); | |
} | |
displayElements(res); | |
}) | |
.catch(err => { | |
displayError(err); | |
console.log(err); | |
}); | |
} else { | |
// older version | |
const http = new XMLHttpRequest(); | |
http.open('GET', url); | |
http.send(); | |
http.onreadystatechange = function() { | |
if (this.readyState === 4 && this.status === 200) { | |
let response = JSON.parse(http.responseText); | |
console.log('Weather Data', response); | |
displayElements(response); | |
} else if (status !== 200){ | |
displayError(`${this.status} Error`); | |
} | |
} | |
} | |
} | |
// perform request | |
window.onload = getWeather(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#app { | |
display: flex; | |
flex-direction: row wrap; | |
justify-content: flex-start; | |
font-family: 'Space Mono', monospace; | |
} | |
.card { | |
border: 1px solid #808080; | |
padding: 0 20px 20px 20px; | |
} | |
.card img { | |
margin-top: -10px; | |
margin-bottom: -20px; | |
margin-left: -5px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment