Showing posts with label yahoo. Show all posts
Showing posts with label yahoo. Show all posts

Thursday, November 12, 2009

Access Yahoo's Weather API via YQL and jQuery

Let me start off by saying that if you want a basic demo of YQL by grabbing an RSS feed check out my first blog post on YQL. In this post I am going to make a little weather widget that grabs the current temperature, weather condition, wind speed and direction, create a link to the full forecast and lastly drop a pretty weather condition graphic as the background of the widget. Then, once I have all that data I am going to display it via jQuery.

So let's get started! Pull up the YQL developer console: https://developer.yahoo.com/yql/console/ and type in:

select * from weather.forecast where location=29201

Select JSON and click test. This shows you the weather data for Columbia, SC in JSON format. The good stuff is located in the within data.query.results.channel. In there you have access to the current temperature, humidity, wind, wind direction and even sunrise and sunset times. So let's start off simple.

Notice the rest query url in YQL console? It reads:
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20location%3D29201&format=json&callback=cbfunc

That is a little tough to work with if you ask me so I like to bring in a little jquery to make this JSON url a little easier to work with and read. Here is a little piece of jquery that does just that for you:

$.YQL = function(query, callback) {
    var encodedQuery = encodeURIComponent(query.toLowerCase()),
        url = 'http://query.yahooapis.com/v1/public/yql?q='
            + encodedQuery + '&format=json&callback=?';
    $.getJSON(url, callback);
};


I generally include this little snippet in a file called jquery.yql.js. After that we can place our YQL query just like in the console. Here is our sample query:

$.YQL("select * from weather.forecast where location=29201",function(data){
            var w=data.query.results.channel;
            $('#weatherTemp').html(w.item.condition.temp+"°");
            $('#weatherText').html(w.item.condition.text);
       });  

This call grabs the weather information for Columbia, SC and injects the temperature and condition text to their corresponding divs. So data.query.results.channel.item.condition.temp = current temperature. and data.query.results.channel.item.condition.text = current condition.

So that was easy, let's grab all the information we want for this demo!

$.YQL("select * from weather.forecast where location=29406",function(data){
            var w=data.query.results.channel;
            var weatherImage="url(http://l.yimg.com/a/i/us/nws/weather/gr/"+w.item.condition.code+"d.png)";
            var wd=w.wind.direction;
            if(wd>=348.75&&wd<=360){wd="N"};if(wd>=0&&wd<11.25){wd="N"};if(wd>=11.25&&wd<33.75){wd="NNE"};if(wd>=33.75&&wd<56.25){wd="NE"};if(wd>=56.25&&wd<78.75){wd="ENE"};if(wd>=78.75&&wd<101.25){wd="E"};if(wd>=101.25&&wd<123.75){wd="ESE"};if(wd>=123.75&&wd<146.25){wd="SE"};if(wd>=146.25&&wd<168.75){wd="SSE"};if(wd>=168.75&&wd<191.25){wd="S"};if(wd>=191.25 && wd<213.75){wd="SSW"};if(wd>=213.75&&wd<236.25){wd="SW"};if(wd>=236.25&&wd<258.75){wd="WSW"};if(wd>=258.75 && wd<281.25){wd="W"};if(wd>=281.25&&wd<303.75){wd="WNW"};if(wd>=303.75&&wd<326.25){wd="NW"};if(wd>=326.25&&wd<348.75){wd="NNW"};
            $('#weatherWidget').css("background-image",weatherImage);
            $('#weatherTemp').html(w.item.condition.temp+"&deg;");
            $('#weatherText').html(w.item.condition.text);
            $('#weatherWind').html(wd +" "+w.wind.speed+"mph");
            $('#weatherLink').html("<a href='"+w.item.link+"'>Full Forecast</a>");
        });

OK, let's go line by line. First off you wil notice that I created weatherImage variable. Yahoo does not give you the full url to the image. I have to build the url and insert the condition code to display the right image. So to make the weatherImage I take the string "http://l.yimg.com/a/i/us/nws/weather/gr/" and add the condition code "30" to it and append the string ".png" to that you get: http://l.yimg.com/a/i/us/nws/weather/gr/30d.png

Yahoo does not give you the text wind direction. It gives you the degree. So if w.wind.direction might equal "90" which equals East. But I actually want to display E or NE. etc... So I wrote a series of if statements to check the direction number and output a string. I know, I know. I could have written a regular expression, but hey, I am a designer. Cut me some slack!

The rest of it just injects all the data into the corresponding divs. So here is a working example:


Please note there is NO server side coding going on. This is just javascript, HTML, and a little css. Speaking of which, here is the html as well:

<div id="weatherWidget" style="background: rgb(51, 51, 51) none no-repeat scroll 0% 0%; border: 10px solid rgb(17, 17, 17); height: 150px; position: relative;">
<div id="weatherDescription" style="left: 200px; position: absolute; top: 40px;">
<div id="weatherTemp" style="font-size: 200%; font-weight: bold;"></div>
<div id="weatherText"></div>
<div id="weatherWind"></div>
<div id="weatherLink"></div>
</div>
</div>

Pretty simple stuff if you ask me. I am going to post some flickr, youTube, upcoming.org, and twitter YQL widgets in the near future. So stay tuned!

Friday, October 23, 2009

YQL allows you to query the entire web

Leave no RSS, XML document, or web 2.0 api untouched! You literally can grab content from anywhere, turn it into JSON data and display the desired information using my old fiend jQuery.
First off check out the YQL developer console: https://developer.yahoo.com/yql/console/
There you can run test queries and view many community tables using popular api's and file formats doing very useful things. For example, if I want to grab the latest 3 posts from my blog I would just put in:
select * from atom where url='http://graphicallyherdingthemasses.blogspot.com/feeds/posts/default' limit 3

And BAM. Right there in the console you can see the feed. If you select JSON and run the test again and copy the generated url you get this...
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20atom%20where%20url%3D'http%3A%2F%2Fgraphicallyherdingthemasses.blogspot.com%2Ffeeds%2Fposts%2Fdefault'%20limit%203&amp;format=json&amp;callback=cbfunc
That's great but how can I put that on MY site? Well, first we need to bring in a little jquery to make this JSON url a little easier to work with and read. Here is a little piece of jquery that does just that for you:

$.YQL = function(query, callback) {
    var encodedQuery = encodeURIComponent(query.toLowerCase()),
        url = 'http://query.yahooapis.com/v1/public/yql?q='
            + encodedQuery + '&format=json&callback=?';
    $.getJSON(url, callback);
};

So now all we need to do is grab the data and display it using a little jquery. First we grab the first 3 posts by our YQL call. Once we get the data we are going to find the individual blog posts and grab the title and the link and append it to the called bloggerWidget.

$.YQL("select * from atom where url='http://graphicallyherdingthemasses.blogspot.com/feeds/posts/default' limit 3",function(data){
            var blogPost=data.query.results.entry;
            $.each(blogPost,function(index, blogPost){
                $('#bloggerWidget').append("<li><a href='"+blogPost.link[4].href+"'>"+blogPost.title.content+"</a></li>");
            });    
        });

Here is it in action:


    No ASP, PHP, JSP, proxies, or cross domain errors... You can do this with ANY feed on ANY site. I am currently working on a site that pulls in data from the yahoo weather api, the flickr api, blogger atom feeds, twitter rss 2.0 feeds, and the youtube api.