It’s best I expand more on APIs. You can peep my previous article https://solomonabu.hashnode.dev/introduction-to-apis where I did an introduction and breakdown to apis.
Without spending much of your time let’s dive into ‘Creating an API-based web app.
we will be applying all that we have learnt about an API (Application Programming Interface) thus far and putting our knowledge to the test.
In this quest, we will be building a simple weather web application that will get the user location from the browser and pass on the data to the Weather API service provider.
We will be using the same API Key and provider from the "Introductions to API" article, so do ensure you have your API key ready.
Learning Outcomes
By the end of this quest, you will be able to:
Fetch location data from a browser
Make requests from an API using required parameters
Use responses from an API to build a web application
Handle raw data and format them using the Math Module
Article Walkthrough
Step 1: Setting Up Our Workspace
Firstly, let us create a new folder for this project. You may name the folder according to your preference, such as weather-api. For this example, our choice of code editor is Visual Studio Code.
Now, create a folder by right-clicking and select “New Folder”. Rename the new folder to “js”. Next, create two more folders and name them “css” and for “img” respectively. We will be storing our CSS files and JavaScript files in their respective folders. Lastly, let’s create the files for HTML, CSS and JavaScript. Create a HTML file called “index.html” and place it in the root folder. Create a JavaScript file called “main.js” and place it inside the “js” folder. Lastly, create a “main.css” file and place it in the “css” folder.
Once you're done, you should have a directory that looks like the 'expected output'.
Expected output
Step 2: Website Structure
Similar to what we did in Multiple Timers Web App, we will be following the same routine of generating a boilerplate and adding the HTML tags to the index.html file.<!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"> <title>Document</title> <script type="text/javascript" src="./js/main.js" defer></script> <link rel="stylesheet" href="./css/main.css"> </head> <body onload="loadSite()"> </body> </html>
In the code above, there is a <link> tag to link the css file we have created and a <script> tag to connect the JavaScript to the HTML file. The code also has a onload attribute in the <body> tag to call the loadSite() function when the body elements are loaded. You will later be coding the loadSite() function in the JavaScript file.
Next, you will be adding the code below within the <body> tag. The code has the classes and id to be referenced by our CSS file later on.
<div class="container"> <p>Stackie123 Weather</p> <h1 id="temperature"></h1> <p id="description"></p> <h2 id="location"></h2> <!-- tables --> <div class="table-container"> <table class="table"> <thead> <tr> <th>City</th> <th>Temperature</th> <th>Humidity</th> <th>Pressure</th> <th>Wind Speed</th> <th>Wind Direction</th> <th>Sunrise</th> <th>Sunset</th> </tr> </thead> <tbody id="table-body"> <tr> <td id="data_city">London</td> <td id="data_temperature">20</td> <td id="data_humidity">20</td> <td id="data_pressure">20</td> <td id="data_wind_speed">20</td> <td id="data_wind_direction">20</td> <td id="data_sunrise">20</td> <td id="data_sunset">20</td> </tr> </tbody> </table> </div> </div>
In the paragraph tag, you will need to replace Stackie123 with your own StackUp username.
We will be using HTML tables to output various parts of the API response. We will be pulling data like the city name, the humidity, weather type, wind data and more. You may see that API is actually very useful and it is rich in data. You may also notice some table data have some values populated. Those are data to be overwritten once we have received the response from the API.
Step 3: Styling our Web App
In this step, we will be adding in the styling to the website by making reference to the HTML elements by their ids and classes. Add the code in 'working code' to the main.css file within your “css” folder.
Working code
body { font-family: 'Roboto', sans-serif; background: #f2f2f2; color: #333; font-size: 16px; line-height: 1.5; margin: 0; padding: 0; height: 100vh; background-size: cover; background-repeat: no-repeat; display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; color: white; text-shadow: 0 0 10px rgba(0, 0, 0, 0.9); } .container{ min-width: 50vw; min-height: 20vh; max-width: 70vw; max-height: 70vh; border: 1px solid #333; border-radius: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 10px; background-color: rgba(255, 255, 255, 0.3); /* background: rgba(0, 0, 95, 0.5); */ } h1,h2{ font-size: 2rem; margin: 0; padding: 0; } p{ font-size: 1rem; margin: 0; padding: 0; } h1{ font-size: 60px; } table{ display: flex; padding: 10px; } tbody{ margin-left: 50px; } tr { display: block; float: left; } td { display: block; text-align: right; } th{ text-align: left; display: block; }
Step 4: Sourcing for Images
Apart from displaying data we have received from the API, we can also use those data to reference the type of data collected. In this web app, we are going to change the background based on the type of weather it is. In our case, we will only be using four weather types.
You may choose to use the images in the 'Resources' section or look for images yourself. Ensure these images are in the img folder. It is preferable to have all four images of the same image format like “PNG” or “JPEG”. Next, rename these images to “clear.jpg”, “cloudy.jpg”, “fair.jpg” and “rainy.jpg” to represent the four different weather conditions.
Resources:https://s3.amazonaws.com/appforest_uf/f1667504558417x306703435803803000/clear.jpg https://s3.amazonaws.com/appforest_uf/f1667504558451x800274353657413200/cloudy.jpg https://s3.amazonaws.com/appforest_uf/f1667504559508x696308981975744400/fair.jpg https://s3.amazonaws.com/appforest_uf/f1667504559793x724633431595768000/rainy.jpg
Step 5: Obtaining User Location
You will now be getting user location through the browser. In order to do so, we will be adding a function in JavaScript. This function is built-in to the browser. However, the browser will request from the user to use their location and the function will return the data only if the user has allowed the usage of their location. Add the code below to the main.js file within the “js” folder.let longitude = "1.360321"; let latitude = "103.846733"; function loadSite () { if (navigator.geolocation) { // device can return its location navigator.geolocation.getCurrentPosition(function(position) { latitude = position.coords.latitude; longitude = position.coords.longitude; getWeather(); }); } }
In this code, we have set 2 variables, latitude and longitude. Essentially when the browser gets the user location, the format will be in the form of a latitude and longitude. We will use this information to fetch from Open Weather Map API later on. We have also used the loadSite() function. This means that once the HTML body element has been loaded, loadSite() will run and request for the user location immediately.
Step 6: Fetching From Our API
Finally, the moment has come for you to call the API. Using the latitude and longitude data we have received from the browser, we pass them along to the API Service provider through the endpoints. We will need the API Key we have gotten from OpenWeatherMap.com.
Copy the code in 'working code' and paste it after the loadSite() function in main.js. You will need to insert the OpenWeatherMap.com API key you previously obtained at “<YOUR API KEY>”.
We will first initialize the variable “url” to be the endpoint. Using string formatting, we will be able to put our API Key, location coordinates into the url. Using the fetch() method, we will be able to get a response from the API Service Provider.
You may also notice that we use a .then() function after our fetch() method. This is because our fetch() is an asynchronous function that requires more time to finish its process. It requires time to fetch information and data from a REST API server. As such, once the process is complete, the .then() function will be executed.
The API will return the data and we will have to convert it to a JSON format. Once we do so, we will be able to access the data from the “json” variable. We can access the weather descriptor by using json.weather[0].name and it will return names like "Rain", "Fair", "Clouds" etc. Using a switch statement, we can check through the various test cases to determine which image we want to switch to, depending on the weather descriptor.
Lastly, once we have a variable to access the information from, we will be able to display it to the document by referencing the element by their id. We can do so by using document.getElementById(). After doing so, the rest is simply referring to the object from the JSON we have collected from the API request. In addition, we also used another function from the Math Module, Math.round() to round up the value to format the number instead of placing a recurring value inside the document.
Open the index.html file in your browser and it should be able to work by now.
Right click on the web page and select inspect element.
Click on the Console tab. Notice that the response object has been printed into the terminal, as shown in 'expected output'. From here you can read all of the data that is coming into the browser based on our request.
The data type we are dealing with is a JSON file or a JavaScript Object Notation. It is a Key Pair value data type. Once we have collected the response, we will just need to reference the property value we need. For example, if we need the temperature, we can access it by json.main.temp. json is a variable within our script.
We can use the Math Module to clean up the data within the project. Some values are recurring values and we can use Math.round() to round up the number.
Lastly, using the switch() method, you are able to display and change the background image of your Web App based on the weather condition.
Working code
function getWeather () { let url =
http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=<YOUR
API KEY> console.log(url); fetch(url) .then(function(response) { return response.json(); }) .then(function(json) { console.log(json); switch(
json.weather
[0].main){ case "Rain":
document.body.style
.backgroundImage = "url('./img/rainy.jpg')"; break; case "Clouds":
document.body.style
.backgroundImage = "url('./img/cloudy.jpg')"; break; case "Clear":
document.body.style
.backgroundImage = "url('./img/clear.jpg')"; break; default:
document.body.style
.backgroundImage = "url('./img/fair.jpg')"; break; } document.getElementById("temperature").innerHTML = Math.round((json.main.temp-273.15)*10)/10 + "°C"; document.getElementById("location").innerHTML =
json.name
; document.getElementById("description").innerHTML =
json.weather
[0].description; document.getElementById("data_city").innerHTML =
json.name
; document.getElementById("data_temperature").innerHTML = Math.round((json.main.temp-273.15)*10)/10 + "°C"; document.getElementById("data_humidity").innerHTML = json.main.humidity + "%"; document.getElementById("data_wind_speed").innerHTML = json.wind.speed + "m/s"; document.getElementById("data_wind_direction").innerHTML = json.wind.deg + "º"; document.getElementById("data_pressure").innerHTML = json.main.pressure + "hPa"; document.getElementById("data_sunrise").innerHTML = new Date(json.sys.sunrise*1000).toLocaleTimeString(); document.getElementById("data_sunset").innerHTML = new Date(json.sys.sunset*1000).toLocaleTimeString(); }); }