Using Yahoo'S Apis To Build A Simple Weather Web Services: The Javascript
Using Yahoo'S Apis To Build A Simple Weather Web Services: The Javascript
Using Yahoo'S Apis To Build A Simple Weather Web Services: The Javascript
The JavaScript The first step is to define two configuration variables in /assets/js/script.js:
These are passed as parameters with the AJAX requests for the location and weather APIs as you will see in a moment. Following the outline in the idea section, we should now look into using the HTML5 Geolocation API to obtain a set of GPS coordinates. This API is supported by all new browsers including IE9 and mobile devices. To use it, we need to test whether the global navigator object has a geolocation property. If it does, we call its getCurrentPosition method passing two event handling functions for success and failure. Here is the relevant code from script.js that does this:
// Does this browser support geolocation? if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(locationSuccess, locationError); } else{ showError("Your browser does not support Geolocation!"); }
function locationError(error){ switch(error.code) { case error.TIMEOUT: showError("A timeout occured! Please try again!"); break;
case error.POSITION_UNAVAILABLE: showError('We can\'t detect your location. Sorry!'); break; case error.PERMISSION_DENIED: showError('Please allow geolocation access for this to work.'); break; case error.UNKNOWN_ERROR: showError('An unknown error occured!'); break; }
The locationSuccess function is where we will be issuing requests to Yahoos APIs in a moment. The locationError function is passed an error object with the specific reason for the error condition. We will use a showError helper function to display the error messages on the screen. The full version of locationSuccess follows:
function locationSuccess(position) { var lat = position.coords.latitude; var lon = position.coords.longitude;
// Yahoo's PlaceFinder API http://developer.yahoo.com/geo/placefinder/ // We are passing the R gflag for reverse geocoding (coordinates to place name) var geoAPI = 'http://where.yahooapis.com/geocode?location='+lat+','+lon+'&flags=J&gflag
s=R&appid='+APPID;
// Forming the query for Yahoo's weather forecasting API with YQL // http://developer.yahoo.com/weather/
var wsql = 'select * from weather.forecast where woeid=WID and u="'+DEG+'"', weatherYQL = 'http://query.yahooapis.com/v1/public/yql?q='+encodeURIComponent(wsql)+'&f ormat=json&callback=?', code, city, results, woeid;
// Issue a cross-domain AJAX request (CORS) to the GEO service. // Not supported in Opera and IE. $.getJSON(geoAPI, function(r){
if(r.ResultSet.Found == 1){
// This is the city identifier for the weather API woeid = results[0].woeid;
// Make a weather API request (it is JSONP, so CORS is not an issue): $.getJSON(weatherYQL.replace('WID',woeid), function(r){
if(r.query.count == 1){
for (var i=0;i<2;i++){ item = r.query.results.channel.item.forecast[i]; addWeather( item.code, item.day +' <b>'+item.date.replace('\d+$','')+'</b>', item.text + ' <b>'+item.low+''+DEG+' / '+item.high+''+DEG+'</b>' ); }
weatherDiv.addClass('loaded');
});
The PlaceFinder API returns its results as plain JSON. But as it is on a different domain, only browsers that support CORS (cross origin resource sharing) will be able to retrieve it. Most major browsers that support geolocation also support CORS, with the exception of IE9 and Opera, which means that this example wont work there. Another thing to consider is that the weather API returns only two days of forecasts, which somewhat limits the utility of our web app, but unfortunately there is no way around it. We are only using the Weather API for temperature data, but it provides additional information that you might find useful. You can play with the API and browse the responses in the YQL console. After we retrieve the weather data, we call the addWeather function, which creates a new LI item in the #scroller unordered list.
function addWeather(code, day, condition){
var markup = '<li>'+ '<img src="assets/img/icons/'+ weatherIconMap[code] +'.png" />'+ ' <p class="day">'+ day +'</p> <p class="cond">'+ condition + '</p></li>';
scroller.append(markup); }
Now we need to listen for clicks on the previous / next arrows, so we can offset the slider to reveal the correct day of the forecast.
/* Handling the previous / next arrows */
// Exit if the requested item does not exist, // or the scroller is currently being animated if (i >= items.length || i < 0 || scroller.is(':animated')){ return false; }
// The first/last classes hide the left/right arrow with CSS weatherDiv.removeClass('first last');
With this our simple weather web app is complete! You can see everything together in /assets/js/script.js. We won't be discussing the styling here, but you can read through /assets/css/styles.css yourself.