
Azure Functions, APIs, and the Weather
I wanted to create a program that answers the question “What should you do tomorrow?” based on the weather forecast. The goal was to help people come up with creative things to do tomorrow and plan out their day. Often, we fall back on the same activities or, if it's a nice day, find out we're too late to book something. Then we have regrets.
This was one of the first multi-layered coding projects I’d ever tackled, but it’s pretty simple with the right API and Azure Functions. In this tutorial blog, I’ve split the work into three parts: the webpage, the HTTP trigger, and the JavaScript.
What you’ll need:
- A Microsoft Azure subscription (you can get one for free for a limited time)
- An account atopenweather.org (this is totally free for the API we’re using unless you want to upgrade)
- Visual Studio Code (and to make things easier, install the Live Server extension – for testing your webpage along the way – the Azure Functions extension, and the Azure App Service extension)
Part #1: The Webpage
This is the easiest part because the webpage is relatively simple. The most important section is creating thediv
andform
elements for the submission form. You need one overalldiv
(I used the id“container”
), inside of which is a hidden div (id“hidden-weather”
) and a form element (id“zipcode-form”
).
<divid="container"><divid="hidden-weather"type="hidden"></div><formid="zipcode-form"onsubmit="handle(event)"></form></div>
Leave theonsubmit
part for later – that comes with the JS, which is Part #3.
Inside theform
element add twoinput
tags. The first creates the zip code input box, and the second creates the submit button, which activates the whole process, with the HTTP trigger function and the API.
<inputtype="text"name="zipcode"id="zipcode-input"accept="5"placeholder="Enter zip code"><inputsize="100"type="submit"value="Get recommendations!"id="submit-button-style"></input>
The rest of the code in this section formats the webpage. The code below would be placed inside thediv
with the id"container"
.
<divid="weather-result"><center><h3>Weather Forecast for Tomorrow:</h3></center></div><br><br><divid="recommendations-result"><center><h3>Recommendations:</h3></center></div>
Now that we have the user interface complete, let's code the Azure function the user will trigger.
Part #2: Azure Functions
This part can get a little complicated because you’re dealing with a lot of things at the same time. I’m just going to cover the most important parts.
Create a Function App resource – once the resource is deployed, create a new HTTP trigger function. Don’t open the trigger yet, though, because you need to install annpm
package in the console. Under Development Tools, open the console and installnode-fetch
. This makes calling the API a lot simpler.
Go back to your HTTP trigger and open the Code + Test tab. Create aconst
outside of the async function calledfetch
.
constfetch=require('node-fetch');
This lets you use thenpm
package that was installed earlier.
We'll then define three constants: the first deals with the zip code, while the next one calls the API, and the final one formats the forecast data as a JSON file.
module.exports=asyncfunction(context,req){context.log('JavaScript HTTP trigger function processed a request.');constzipcode=(req.query.zipcode||(req.body&&req.body.zipcode));constapiResult="";constjsonResult=awaitapiResult.json();context.res={// status: 200, /* Defaults to 200 */body:jsonResult};}
Let's take a look at theapiResult
constant a bit more closely because that's the most important one.
In your Open Weather account, go to the free 5 day, 3-hour forecast API documentation page here:https://openweathermap.org/forecast5#zip. Go to the “by ZIP code” section and copy the posted link. This link calls the 5 day, 3-hour forecast API.
api.openweathermap.org/data/2.5/forecast?zip={zipcode},{countrycode}&appid={APIkey}
Back in the HTTP trigger, let's modify ourapiResult
using this information, withawait fetch ()
and the URL you just copied.
constapiResult=awaitfetch("https://api.openweathermap.org/data/2.5/forecast?zip={zip code}");
Then, let's make sure it's actually going to use the zip code entered when calling the API, by replacing the placeholder{zip code}
with our variablezipcode
:
constapiResult=awaitfetch("https://api.openweathermap.org/data/2.5/forecast?zip="+zipcode);
Next, let's add a few parameters to limit the hours to a full day (i.e.cnt
(or "count") as8
, for 8 3-hour segments) and use imperial units (instead of scientific ones, like Kelvin).
constapiResult=awaitfetch("https://api.openweathermap.org/data/2.5/forecast?zip="+zipcode+"&cnt=8&units=imperial");
Finally, insert your Open Weather API key at the end, by tacking on&appid=
, followed by your API key.
Part #3: The JavaScript
I’m not going to explain all of the JS either, but I am going to describe how to access certain information and call the trigger function.
asyncfunctionhandle(event){event.preventDefault();varzipcode=document.getElementById("zipcode-input").value;console.log(zipcode);constresp=awaitfetch("https://weatherapifunction.azurewebsites.net/api/WeatherAPI?zipcode="+zipcode,{method:"POST",});vardata=awaitresp.json();console.log(data);constweatherForecastForTommorowNoon=data.list[6];constweatherForecastCity=data.city;varoutput;// Abbreviated algorithmif(weatherForecastForTommorowNoon.pop>=.01){output="string of rainy day activities";}elseif((weatherForecastForTommorowNoon.pop>=.01)&&(weatherForecastForTommorowNoon.weather[0].description=="snow")){output="string of snowy day activities";}varweatherRegular=` <!Forecast data from API> `;varrecommendations=` <p>${output}</p> `;$("#weather-result").html(weatherRegular);$("#recommendations-result").html(recommendations);}
The most important section of the code above is theresp
constant. It calls the Azure trigger function using the trigger’s URL and sends the zip code entered on the website to the trigger function (by accessing theform
element“zipcode-input”
created earlier usingdocument.getElementById
).
asyncfunctionhandle(event){event.preventDefault();varzipcode=document.getElementById("zipcode-input").value;console.log(zipcode);constresp=awaitfetch("https://weatherapifunction.azurewebsites.net/api/WeatherAPI?zipcode="+zipcode,{method:"POST",});
Now, the entered zip code is run through the trigger function and used when the API is called. It usesPOST
rather thanGET
method, as the zip code is being sent to the Azure trigger function.
Noticeconsole.log(data)
– now that the data is logged in the console, we can access it using the next two constants. ConstweatherForecastForTomorrowNoon
accesses tomorrow's three-hour forecast data from 1 pm to 4 pm. The next constant accesses the city outputted in the console – it was only used in displaying the general forecast on the website, not in generating activity recommendations.
console.log(data);constweatherForecastForTommorowNoon=data.list[6];constweatherForecastCity=data.city;
Next comes the algorithm – basically, create a list of activities, and then match weather to those activities (you need snow for sledding and skiing, sun and wind for sailing and flying a kite). Create if/else statements for these conditions and activities – ifweatherForecastForTomorrowNoon.{enterWeatherConditionHere}
is<
,>
, or=
a certain temperature or measurement, make the variableoutput
equal a string with the activities that are recommended based on the weather conditions.
// Abbreviated algorithmif(weatherForecastForTommorowNoon.pop>=.01){output="string of rainy day activities";}elseif((weatherForecastForTommorowNoon.pop>=.01)&&(weatherForecastForTommorowNoon.weather[0].description=="snow")){output="string of snowy day activities";}
After you have created all of these conditions (based on humidity, temperature, wind speed, and precipitation) create four solely weather-based if/else statements that cover all temperatures possible (but no other weather conditions). There may be a day without wind or precipitation, but there will always be temperature.
elseif(weatherForecastForTommorowNoon.main.temp<=30){output="string of cold activities";}elseif((weatherForecastForTommorowNoon.main.temp>=31&&weatherForecastForTommorowNoon.main.feels_like<=60)&&weatherForecastForTommorowNoon.pop==0){output="string of chilly day activities";}//Add more conditionals to the end
Now there are no holes in the algorithm. Add these temperature-based statements to the end of your conditionals so that the forecast data is run through these last (because these are the most general statements, and conditionals should always be ordered with the most specific statement first and the most general statement last).
Final Result
Your project should now look something like this:https://github.com/TheDirector23/come-rain-or-shine
Of course, you can always add improvements! The recommendations could be customized based on user inputs (location, personality questions, preferred activities). The recommendations could also be linked to local businesses based on the entered zip code as well (a local marina might be linked to a recommendation to go sailing). Other locations and recommendations could be offered if the conditions aren't great.
That's about it! Hopefully now you're ahead of the weather when it comes to planning for tomorrow.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse