In my first exploration of the JSON data interchange format, I used it in its most basic way possible. I attached a script (from delicious) to a page and simply used the built-in object created by their implementation to generate an unordered list of my recent del.icio.us posts. While it showed how easy it is to use the O, a handy, structured, Javascript Object, provided by JSON, it didn't really illustrate how to manipulate the page with new data after page load. That is, after all, a very now thing to do, so it's kind of important. This article will examine how to dynamically load a JSON feed and how to get data out of Twitter and into a usable form using a callback.
While one can load JSON using XMLHttpRequests, the real benefit of JSON is to be able to load data from a third party without worrying about the browser security model and without having to rely on a local pass through file. So, we're going to load the data without XHR in this example. Instead we're going to load it using dynamic script tags.
Here's the function I'm using in my example:
function twitter_me() {
var twitter_JSON = document.createElement("script");
twitter_JSON.type="text/javascript"
twitter_JSON.src="http://twitter.com/statuses/user_timeline/rob_react.json?callback=twitter_callback&count=10"
document.getElementsByTagName("head")[0].appendChild(twitter_JSON);
}
First I create a new script element in the document, then I set the type and source. The source is the interesting part. As you can see, after the URL for the JSON document representing my Twitter updates, I append a query string. The first argument for that query string (callback=twitter_callback) is where the magic happens. There I'm defining the function that will be called when the script is attached to the document. To see what happens compare the first few characters of the JSON script called with and without the callback.
Here it is, as referenced in the above code
twitter_callback([{"source":"web","text":"426 queries in 107.66 milliseconds. drupal is teh awesome",
and called without the callback (but with the count, so the data structure returned is the same)
[{"source":"web","text":"426 queries in 107.66 milliseconds. drupal is teh awesome",
Notice the function referenced in the first example. Right there, as soon as the JSON document is loaded, JavaScript executing the callback function with the JSON object as an argument. I'm a JavaScript geek and all, so I'm biased... but that's just plain cool.
So what happens next, you ask? Well, since I defined a function called twitter_callback, that function is run and I'm able to do all sorts of cool things with the provided object. Here's the function in all its glory:
function twitter_callback(twit) {
//this is the div I'm writing the content to
var t_div = document.getElementById("twitter");
//these are some other variables, mostly
//placeholders so that the code is a little clearer
var who,what,when,icon, bgcolor
//start the ul
t_div.innerHTML = "<ul>"
//loop through the twit object
for (i=0;i<twit.length;i++) {
//Look at me use the JavaScript modulus operator to do even/odd rows.
if(i % 2) {
bgcolor="#efefef"
} else {
bgcolor="#ddd"
}
//Right here, I've broken out the separate bits of the string into placeholder variables
//so you can more easily see the dot notation and array indices in place
//once you figure out the structure it's dead easy to reference data in an Object
icon=twit[i].user.profile_image_url;
who=twit[i].user.name;
what=twit[i].text;
when=twit[i].created_at.substr(0,19);
//and here I mash it all up into a fancy li
t_div.innerHTML +="<li style='background:"+bgcolor+" url("+icon+") no-repeat'><strong>"+who+"</strong>: "+what+" ("+when+" GMT) </li>"
}
//and close the UL
t_div.innerHTML += "</ul>"
}
Here it is in action (be patient, Twitter can be slow):
Call me crazy, but that's something like 75% away from being a widget and there are no cross domain concerns to deal with so it could easily be spread far and wide. There's a lot to like right there
That's it for this time. Feel free to ping me with questions or comments.
Next up, as I mentioned, one can load JSON via XMLHttpRequest, so I'll be building an example that does just that. There's a wrinkle tossed in with that technique that will make things, if not tougher, a little less cool (eval(), I'm looking in your direction.) More on that when I put it all together.