So recently I was thinking of a new project and thought about making a Weather app.
I disregarded it for a bit but recently because of the weather I found myself checking multiple weather sources for the weather and thought about making a weather app but having multiple sources for the weather!
So that is the plan!
Let’s Go!
We are gonna be making the weather app with Html, CSS, and Javascript.
Now we are planning on using multiple APIs for the weather.
There is this amazing repository that stores a lot of free APIs that you can use for your projects: https://github.com/public-apis/public-apis
We are gonna be using the OpenWeatherMap API the GoWeather API and the Wttr.in API.
We are gonna create an input field and a button to get the weather for the city that the user inputs.
<input type="text" id="city" placeholder="Enter City Name">
<button id="getWeather">Get Weather</button>
To detect when the user clicks the button we are gonna use the addEventListener method.
document.getElementById('getWeather').addEventListener('click', function(){
//code here
})
If we don’t wanna use the addEventListener method we can use the onclick on the button element.
<button id="getWeather" onclick="getWeather()">Get Weather</button>
function getWeather(){
//code here
}
Now we are gonna get the value of the input field and store it in a variable.
var city = document.getElementById('city').value;
Now how are we gonna be able to call these APIs?
Well, we are gonna be using the Fetch API to call the API.
Here we are gonna call OpenWeatherMap API:
Note: OpenWeatherMap requires an API key.
fetch('https://api.openweathermap.org/data/2.5/weather?q='+city+'&appid='+apiKey)
Here we are gonna call GoWeather API:
fetch('https://goweather.herokuapp.com/weather/'+city)
Here we are gonna call Wttr.in API:
fetch('https://wttr.in/'+city+'?format=j1')
Now we are gonna get the data from the APIs and display it on the screen.
First, we need to make an element where we will be able to display the data.
<div id="weather"></div>
Now we are gonna get the data from the APIs and display it on the screen.
fetch('https://api.openweathermap.org/data/2.5/weather?q='+city+'&appid='+apiKey)
.then(response => response.json())
.then(data => {
var weather = document.getElementById('weather');
weather.innerHTML += "OpenWeatherMap<br>" + data.weather[0].description;
})
fetch('https://goweather.herokuapp.com/weather/'+city)
.then(response => response.json())
.then(data => {
var weather = document.getElementById('weather');
weather.innerHTML += "GoWeather<br>" + data.description;
})
fetch('https://wttr.in/'+city+'?format=j1')
.then(response => response.json())
.then(data => {
var weather = document.getElementById('weather');
weather.innerHTML += "Wttr<br>" + data.current_condition[0].weatherDesc[0].value;
})
The APIs Have more data that you can display but I just displayed the weather description. But they have data such as temperature, humidity, wind speed, pressure, etc.
Now we need to display an icon for the weather.
Based on the weather description we are gonna display an icon.
Where are we gonna get the icons from?
OpenWeatherMap has a Weather Icons page where you can get the icons.
So we are gonna use that.
fetch('https://api.openweathermap.org/data/2.5/weather?q='+city+'&appid='+apiKey)
.then(response => response.json())
.then(data => {
var weather = document.getElementById('weather');
weather.innerHTML += "OpenWeatherMap<br>" + data.weather[0].description + "<br><img src='http://openweathermap.org/img/wn/"+data.weather[0].icon+".png'>";
})
Because the other APIs don’t have icons we are gonna use the Weather Icons of OpenWeatherMap and check if the weather description includes a certain word and display the icon based on that.
We are gonna create a function for that where it will return the id that we will use for the icon using a switch statement.
function getIcon(description){
var id;
switch(description){
case description.includes("clear"):
id = "01d";
break;
case description.includes("few clouds"):
id = "02d";
break;
case description.includes("clouds"):
id = "03d";
break;
case description.includes("rain"):
id = "10d";
break;
case description.includes("thunderstorm"):
id = "11d";
break;
case description.includes("snow"):
id = "13d";
break;
case description.includes("mist"):
id = "50d";
break;
default:
id = "01d";
break;
}
return id;
}
Now we are gonna use the function to display the icon along with the weather.
fetch('https://goweather.herokuapp.com/weather/'+city)
.then(response => response.json())
.then(data => {
var weather = document.getElementById('weather');
weather.innerHTML += "GoWeather<br>" + data.description + "<br><img src='http://openweathermap.org/img/wn/"+getIcon(data.description)+".png'>";
})
fetch('https://wttr.in/'+city+'?format=j1')
.then(response => response.json())
.then(data => {
var weather = document.getElementById('weather');
weather.innerHTML += "Wttr<br>" + data.current_condition[0].weatherDesc[0].value + "<br><img src='http://openweathermap.org/img/wn/"+getIcon(data.current_condition[0].weatherDesc[0].value)+".png'>";
})
When getting information such as the country name from the API we are gonna get the country code but we can use Intl.DisplayNames to get the country name.
let regionNames = new Intl.DisplayNames(["en"], { type: "region" });
regionNames.of("US"); // "United States"
What regionNames does is that it will return the country name based on the country code.
Now we are gonna add some styling to the page.
body {
background-color: #87CEEB;
color: #ffffff;
font-family: Arial, Helvetica, sans-serif;
font-size: 1.2em;
margin: 0;
padding: 0;
}
I found a cool idea of having a card for the weather https://codepen.io/tutsplus/details/gObLaEP
Where you are able to have multiple cards and multiple locations. So we are gonna make that.
Basically how it works is by having a container for the cards with a display of a grid.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: 20px;
padding: 20px;
}
What grid-template-columns does is it will create columns for the cards and repeat them based on the size of the screen.
So if the screen is big it will create more columns and if the screen is small it will create fewer columns.
I open-sourced the code for the weather app on my Github so you can check it out here: https://github.com/Arisamiga/Weather-App
You can also check out the live version here: https://arisamiga.github.io/Weather-App/
This was a very nice project to make as I got to work with multiple APIs and learn more about APIs as well as managing data from these APIs. I also learned more about the grids in CSS.
Hope you enjoyed this project and Thanks so much for reading :D