CGX Blog We'll see where this takes us.

1Mar/111

How to Parse Facebook’s Graph API JSON Response using JQuery

Facebook has provided an excellent resource to developers by allowing us to pull streams of publicly available information (from personal profiles, group pages, company pages, etc.) and format them however we like. That is, we are not required to include the cookie cutter "facebook feed" widget in order to get all that functionality.

I will say that the documentation is something to be desired. Facebook's documentation will give you a reasonable overview but lacks sufficient examples and depth. Below I have shared some of my experience with pulling facebook's data as a JSON response and parsing using JQuery.

The Basics

Pretty Klicks wrote a wonderfully succinct post on this topic, so please read this first. In this article you will learn how to include jQuery in your site, call upon facebook's graph api for a JSON response, parse the response using jQuery, and build a list with your fetched results.

One Step Further

I made a few modifications to their underlying script in order to add a bit of reusability and additional functionality. See below for more detail on how to separate list generation into a reusable function, add images and links in your list, and add an ajax-esq loading graphic:

Creating a Function for Reusability

I separated out the list generation into its own function so I can call it multiple times with different parameters and achieve 'show more' and 'show less' functionality. That is, I can call it once with an offset of 0 and a limit of 5 to get my 5 most recent results; I can then call the function again with any offset and any limit if I want to show a different range of posts. Your fbFetch() function should now look like this:

/* Call fbFetch with offset and limit passed through the call */
function fbFetch(o,l){
  /* Set Url of JSON data from the facebook graph api.
    * Make sure callback is set with a '?' to overcome the
    * cross domain problems with JSON
    */
    var url = "http://graph.facebook.com/survivedgear/feed?limit=" 
    + l + "&offset=" + o + "&callback=?";
 
  /* Call listGenerator and specify the url with JSON content.
    * Also set initial div height (50px in this case)
    */
    listGenerator(url,50); 
}

The listGenerator() function has 5 primary actions:

  1. Immediately sets the height of our primary container div (#fb_feed) to the value passed from the function call. In the original call, when the page is loaded, we have set this container to 50px per the call in fbFetch. In the future, this parameter helps us maintain the container's height when loading new content so it doesn't instantly shrink then expand when the new content has loaded.
  2. Replaces any content in our primary container div with the loading graphic.
  3. Calls jQuery's $.getJSON function and pulls the JSON content from the url that was passed to the listGenerator function when it was called.
  4. Loops through the JSON data, creates variables from relevant data, and builds a list one data block at a time.
  5. Finally, we fade the current content out (the loading graphic), replace the content (with the newly created list), and fade the content back in. Note that we reset the container's height to "auto" so the new content determines the height.
function listGenerator(list_url,list_height) {
 
 //Ensure the box maintains its height during refresh
 $("#fb_feed").css("height",list_height+"px");
 //Replace content with animation until call has been made and new content refreshes
 //The loading graphic is set as a background image to #loading_div in our CSS file.  You can simply
 // include the image here if you prefer.
 $("#fb_feed").html('<div class="loading_div"></div>');
 
 //Use jQuery's getJSON method to fetch data from url
 //Then create our unordered list with the relevant data.
 $.getJSON(list_url,function(json) {
 
  var html = "<ul id='feed_list'>";
 
  //loop through and within data array to retrieve the variables.
  $.each(json.data,function(i,fb){
   //Create variables for anything we want in our list
   //This could be the message, a link, an image, etc.
   //Only 2 are shown below but it can be anything found in your JSON response
   var msg = (typeof(fb.message) != "undefined") ? fb.message : "";
   var link = (typeof(fb.link) != "undefined") ? fb.link : ""; 
 
   //build html for this list item
   html += "<li>";
   html += "<a href='" + link + "' class='fb_link' target='_blank'>"
        + msg 
        + "</a>";
   html += (pic != "") ? "<img src='" + pic + "' />" : "";
   html += "</li>";
 
  }); /* end .each */
 
  html += "</ul>";
 
  //Animation once data is fetched -- pay attention to the HEIGHT
 
  $('#fb_feed').animate({opacity:0}, 500, function(){
    $('#fb_feed').html(html);
    //reset div height to auto so content sets height
    $("#fb_feed").css("height","auto"); 
  });
 
  $('#fb_feed').animate({opacity:1}, 500);
 
 }); /* end getJSON */
} /* end listGenerator */

Pulling Images and Links

You can easily pull images in the same way you generated the list above. Simply add

var pic = (typeof(fb.picture) != "undefined") ? fb.picture : "";

to your variable definitions and then embed them as you would any other variable, only this time inside an img tag!

Note: You will notice that I use PHP's If/Else Shorthand to check whether variables are empty in my JSON data. Even if you fully expect a variable to exist in every response it's good practice to check so you can control your variable definition and not have "pic" assigned to "undefined". For more information on this shorthand, check out David Walsh's explanation.

Handling Nodes A Few Levels Deep

You will notice that the response you get back has two nodes at the upper level: "data" and "paging". Most of the good stuff is within the "data" block, which is why, in the listGenerator's $.each loop, we loop through "json.data". In this block you will see "id", "from", "message", etc., which are directly addressable inside the $.each loop by your callback function's 'value' name (in the example above we have a function(i,fb), so "i" is the key and "fb". This makes it easy to print the feed item's id by defining a variable with fb.id, for example.

What about the "from" node? You'll notice that within "from" are more pieces of information: "name", "category", and another "id". To address those, you need only define a variable with "fb.from.name", "fb.from.category", and "fb.from.id".

Arrays Within your Response

What happens if you expect to have a data item that contains a repeating list of information? A good example of this would be a feed where you can have 0, 1, or more images for any given post. The best way to handle this is to define a variable "pic" that passes the "image" variable to a function whose job it is to loop through the nested elements, define an array, then return that array. See the code below for a simple example:

/* CALL WITHIN YOUR MAIN $.each LOOP
  * keep in mind, my facebook feed does not have an "images" node so this is a hypothetical
  * example.  I use BigCartel for the survivedGEAR shop, which does have multiple thumbnails
  * for each product, and that's why I need this function.
  */
var pic = getThumbSource(fb.images);
/* Collect image data node, loop through it to create an array of images */
function getThumbSource(image_data) {
 
  var arr = new Array();
  if (image_data.length > 0) {
    $.each(image_data,function(i,img){
      arr[i] = (typeof(img) != "undefined") ? img : "";
    });
  } else {
    //INSERT GENERIC THUMBNAIL IMAGE
    arr[0] = "/images/generic.jpg";
  }
 
  return arr;
}
/* BACK IN YOUR $.each LOOP
  * When you then address your "pic" variable later, you can do it like I do below
  * This assumes there is a "url" and "name" node within the original "images" array
  */
html += "<img src='" + pic[0].url + "' alt='" + pic[0].name + "' />;

AJAX Style Loading Graphic

This is nothing more than replacing the "Loading..." text from the Pretty Klicks example with a .gif file. Sure it's simple but it adds a nice flare. If you don't feel like creating your own (like the one below, which I made for survivedGEAR), then Check This Out.

This is a simple loading graphic. To turn this into a loading bar, just repeat the graphic as a background on a pre-sized element!

Comments (1) Trackbacks (0)
  1. api request returns json files and not html/xml browser content


Leave a comment


*

No trackbacks yet.