One of the relatively tough challenges on freecodecamp is building a weather app . The idea is quite simple. Get weather data from the provided API, build a function to convert temperature from degrees C to Fahrenheit, and display the current weather.
In this article, I will not explain and instruct on how to solve this problem thoroughly and in detail, but this can be a good start, if you do not know what to do.
What I will show you, is how to use Vue and Axios to connect to the OpenWeatherMap API , get weather data from a town (London) and display it.
OpenWeatherMap API
To connect to the API you need an API key, otherwise the server will deny your connection.
You can get the API key for free by clicking on the subscribe button under “Current Weather Data” here .
The API will return you the data in JSON format, but you’ll need to provide a few things to get it:
- Endpoint
- API Key
- The unit to get the data (degrees C, degrees F) – default is English
- City name, coordinates, zip code or city id
You can check the parameters the API asks you to pass in order to get the JSON data from this page.
In this article, I declare the number (degrees C) as the unit and London as the city name. So the API link would look like this:
1 2 | http://api.openweathermap.org/data/2.5/weather + ?q=London + &?units=metric + &APPID={API KEY} |
We’ve broken the link down, so you can see how to add parameters to the API endpoint to get the data you want.
The complete link API should look like this:
1 2 | http://api.openweathermap.org/data/2.5/weather?q=London&?units=metric&APPID={API KEY} |
If you add your API key at the end of the link and paste it into the browser, you’ll get all the data you need. Now, all we have to do is get that data into Vue.
Get weather data with Axios
In Javascript, you can use different tools to get data from an API. In this article, I am using axios. The way you get data from the API doesn’t really change much. If you use a different tool, you should not have any problems. To use axios you can do npm axios
install or add CDN link <script src = "https://unpkg.com/axios/dist/axios.min.js"> </script>
to your page friend. In this article, I will use axios through CND.
The code that you need to write is quite simple. First we call axios, then we make a request from a URL and then we will get a response or an error if it is returned. The code will look like this:
1 2 3 4 5 6 7 8 9 | axios .get(url) .then(response => { console.log(response.data); }) .catch(error => { console.log(error); }); |
If you are wondering why we received the response.data
data rather than the response
, the reason for this is simple. The response will not only return the data, but also the status code, title, and type of request made. Use the openweathermap URL and add another console.log (response)
; and see what you get when you run the code.
Create Vue app
I will not go into depth about VueJs or how to create an application with it. But the basic thing is that you create an app by activating the Vue object into an id div.
A Vue application would look like this:
1 2 3 4 5 6 7 8 9 10 | let weather = new Vue ({ el: "#app", data: { }, methods: { } }) |
The el
parameter is the id of the div inside your html. This div id is usually called an app
but you can name it anything you want, just make sure you change the el
inside the Vue object.
The data
parameter contains all the data you might need for your application, normally you would create variables here and then use or modify them. This is also where VueJs will try to get the variable names to translate the {{name}}
tags in our HTML.
The methods
parameter is where you specify all the functions you might want to call while using the application.
To use VueJs, you must install it with the command npm install vue
or add the CDN link <script src = "https://cdn.jsdelivr.net/npm/ [email protected] /dist/vue. js "> </script>
on your page.
I hope this brief and quick introduction will help you understand everything with Vue if you are new to this framework.
Building the application
Now that we have a basic knowledge of how to connect to the OpenWeatherMap API, how to use axios, and how to create a Vue application, I will show you how to create a weather application.
HTML & CSS
The HTML for the application will be pretty basic. The page will have a background and div in the middle with id = “app” that Vue will use. This div will also have a simple background image just to make it look better.
So let’s start by generating HTML code. We’ll import the css and js files to have a working website, we’ll also import VueJs, axios, and two fonts that we’ll be using in the app.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>Weather App</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <link href="https://fonts.googleapis.com/css?family=Montserrat:extra-light|Vast+Shadow" rel="stylesheet"> </head> <body> <div id="app"> </div> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="main.js"></script> </body> </html> |
Now that all the necessary files are imported and the page has a title, we will create a frame for our div. In order for your data to be displayed you will use the format {{variableName}}
, this variableName
name will be the name used in the data
in our Vuejs application.
HTML will be divided into three parts. The top left section shows the icon, current weather and weather description. The top right section will display the minimum and maximum temperatures for the day. Finally is the bottom section where we will display other information such as humidity, pressure, sunrise / sunset time and wind speed.
<Div id = "app">
would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <div id="app"> <div id="weather"> <img src="images/sunny.svg"> {{overcast}} <span class="temperature">{{currentTemp}}°</span><br> <span id="temp-values">Min {{minTemp}}° <br> Max {{maxTemp}}°</span> </div> <div id="info"> <img class="icon" :src=icon> {{sunrise}} <img class="icon" src="images/sunset.svg"> {{sunset}} <img class="icon" src="images/humidity.svg"> {{humidity}} <img class="icon" src="images/pressure.svg"> {{pressure}} <img class="icon" src="images/wind.svg"> {{wind}} </div> |
Now that the web page frame is finished, we need to update the main.css
file to make the page look a little better. Note: The code that I will show you here is not responsive and it’s a bit confusing. I’m sure there’s a better way to do it, but it will suit the purpose of this tutorial.
main.css File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | body { background: #3d4869; /* Old browsers */ background: -moz-linear-gradient(#3d4869, #263048) fixed; /* FF3.6-15 */ background: -webkit-linear-gradient(#3d4869,#263048) fixed; /* Chrome10-25,Safari5.1-6 */ background: linear-gradient(#3d4869,#263048) fixed; /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ background-repeat: no-repeat; font-family: 'Montserrat', sans-serif; font-weight: 100; text-shadow: 0px 0px 2px #000000; color: #ffffff; } #app { background: url(images/waves.svg) no-repeat; width: 520px; height: 170px; position: absolute; top: 35%; left: 35%; } #weather { padding: 15px; vertical-align: middle; } .temperature { font-family: 'Vast Shadow', cursive; font-size: 40px; vertical-align: top; position: absolute; left: 80px; } #temp-values { text-align: right; text-justify: distribute; display: block; position: relative; top: -60px; } #info { padding-left: 20px; position: relative; top: -20px; } .icon { position: inherit; top: 2px; padding-left: 8px; } |
index.html file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>Weather App</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <link href="https://fonts.googleapis.com/css?family=Montserrat:extra-light|Vast+Shadow" rel="stylesheet"> </head> <body> <div id="app"> <div id="weather"> <img src="images/sunny.svg"> {{overcast}} <span class="temperature">{{currentTemp}}°</span><br> <span id="temp-values">Min {{minTemp}}° <br> Max {{maxTemp}}°</span> </div> <div id="info"> <img class="icon" :src=icon> {{sunrise}} <img class="icon" src="images/sunset.svg"> {{sunset}} <img class="icon" src="images/humidity.svg"> {{humidity}} <img class="icon" src="images/pressure.svg"> {{pressure}} <img class="icon" src="images/wind.svg"> {{wind}} </div> </div> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="main.js"></script> </body> </html> |
If you try to open the page, you’ll notice that the app doesn’t look really great at the moment, it’s because we don’t have Vue doing the heavy lifting for us. Go ahead and fix this.
Vue
Vue and axios have been imported via the script tag located in our html code, which means we are ready to start shaping our application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | let weatherApp = new Vue ({ el: '#app', data: { }, methods: { getWeather() { }, } beforeMount() { this.getWeather(); } }); |
The code looks pretty simple, we instantiate a new Vue application attached to the div with the id app
. Inside the Vue application, we declare all necessary variables inside the data
, which will be the variables we use to fill in information obtained through the API.
Also, we declare a method called getWeather
, this is the method that will use axios to get all the information we need from the OpenWeatherMap API.
We want the weather app to display current weather and other weather information like:
- Minimum temperature of the day
- Maximum temperature of the day
- Sunset time
- Sunrise time
- Wind speed
- Pressure
- Percent moisture
The API will return all of these details, so there’s not much we need to do. Inside our Vue object, we will declare all the variables we need to update the tags ({{variableName}})
in our HTML, after connecting to the API and getting the data. necessary.
The data
object inside VueJs will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 | data: { currentTemp: '', minTemp: '', maxTemp:'', sunrise: '', sunset: '', pressure: '', humidity: '', wind: '', overcast: '', icon: '' }, |
Get data from the API using Axios
The response from the Openweathermap API would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | { "coord": { "lon": -0.13, "lat": 51.51 }, "weather": [ { "id": 803, "main": "Clouds", "description": "broken clouds", "icon": "04d" } ], "base": "stations", "main": { "temp": 24.82, "pressure": 1016, "humidity": 51, "temp_min": 23, "temp_max": 27 }, "visibility": 10000, "wind": { "speed": 8.2, "deg": 270 }, "clouds": { "all": 75 }, "dt": 1534695600, "sys": { "type": 1, "id": 5091, "message": 0.003, "country": "GB", "sunrise": 1534654394, "sunset": 1534706018 }, "id": 2643743, "name": "London", "cod": 200 } |
We will use this example of axios to build getWeather
. This method will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | getWeather() { let url = "http://api.openweathermap.org/data/2.5/weather?q=London&?units=metric&APPID={API KEY}"; axios .get(url) .then(response => { this.currentTemp = response.data.main.temp; this.minTemp = response.data.main.temp_min; this.maxTemp = response.data.main.temp_max; this.pressure = response.data.main.pressure; this.humidity = response.data.main.humidity + '%'; this.wind = response.data.wind.speed + 'm/s'; this.overcast = response.data.weather[0].description; this.icon = "images/" + response.data.weather[0].icon.slice(0, 2) + ".svg"; this.sunrise = new Date(response.data.sys.sunrise*1000).toLocaleTimeString("en-GB").slice(0,4); this.sunset = new Date(response.data.sys.sunset*1000).toLocaleTimeString("en-GB").slice(0,4); }) .catch(error => { console.log(error); }) } |
As you can see with the JSON response we received from the API, the above code simply assigns each bit of the data retrieved from the API to the variables declared in the data
, which will allow us to use it. Use data anywhere in the application. Notice that we are adding something to some variables.
In the icon
we add the path for the image folder, the filename and the file extension. When Vue runs, it will change the image’s src
to whatever is inside the icon
.
As for the filename, we will cut the string we get from the API from the character above index 0 to the character at index 2 – this is because openweathermap changes the icon
name depending on whether it’s day or night. .
sunrise
and sunset
are out in the Unix format, so we just need to convert the time to human speech format and then cut the string to get only the hours and minutes.
Your main.js file and the Vue application should now look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | let weatherApp = new Vue({ el: '#app', data: { currentTemp: '', minTemp: '', maxTemp:'', sunrise: '', sunset: '', pressure: '', humidity: '', wind: '', overcast: '', icon: '' }, methods: { getWeather() { let url = "http://api.openweathermap.org/data/2.5/weather?q=London&units=metric&APPID={Your API Key}"; axios .get(url) .then(response => { this.currentTemp = response.data.main.temp; this.minTemp = response.data.main.temp_min; this.maxTemp = response.data.main.temp_max; this.pressure = response.data.main.pressure; this.humidity = response.data.main.humidity + '%'; this.wind = response.data.wind.speed + 'm/s'; this.overcast = response.data.weather[0].description; this.icon = "images/" + response.data.weather[0].icon.slice(0, 2) + ".svg"; this.sunrise = new Date(response.data.sys.sunrise*1000).toLocaleTimeString("en-GB").slice(0,4); this.sunset = new Date(response.data.sys.sunset*1000).toLocaleTimeString("en-GB").slice(0,4); }) .catch(error => { console.log(error); }); }, }, beforeMount() { this.getWeather(); }, }); |
Replace {Your API Key}
with the API key you got from openweathermap and reload the page, you should see the application with the current weather data now.
summary
Thank you everyone for taking the time to this rather long post. I hope you learned how to use axios and Vue together to get data from the API. If you have any suggestions or need to explain something, please comment below for yourself. Link original post: here