Skip to content

Instantly share code, notes, and snippets.

@iamsainikhil
Last active May 16, 2019 17:28
Show Gist options
  • Save iamsainikhil/c82a9ee37afa4169602579f5c9271346 to your computer and use it in GitHub Desktop.
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
<!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>
// 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();
#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