Client-side Twitter Integration with Ajax

In our first client-side example we are going to integrate jQuery Mobile with Twitter’s RESTful API. Twitter is a very popular social media site which allows users to send out, or “tweet” brief messages about topics, events, or random opinions. In our movie app, it may be valuable to allow users to search Twitter in real-time for feedback on a movie they might be interested in. For instance, in addition to viewing others’ reviews of a particular movie, we may want to provide a convenient link to Twitter that displays the latest tweets about it. On our user review page, we have added a Twitter button to the header that users may click to view the latest tweets about the movie (see Figure 9–1 and its related code in Listing 9–1).

__________

1 See http://dev.twitter.com/console.

2 See http://developer.linkedin.com/community/apis.

3 See http://developers.facebook.com/.

images

Figure 9–1. Twitter button in header of movie review page

Listing 9–1. Twitter button in header of movie review page (ch9/reviews.html)<div data-role="page" id="reviewsPage">
    <div data-role="header">
        <h1>Reviews</h1>
        <a href="twitter.html" id="twitterBtn" class="ui-btn-right"
                data-icon="custom" data-iconpos="notext"></a>
    </div>
    ...
</div>

When users click the Twitter button, we will search Twitter for the most recent tweets for the current movie and load the results onto our Twitter results page (see Figure 9–2 and its related code in Listing 9–2).

images

Figure 9–2. Twitter results page

Listing 9–2. Twitter results page (ch9/twitter.html)<div data-role="page" id="twitterPage">
        ...
        <div data-role="content">
          <ul id="tweet-list" data-role="listview" data-inset="true">
            <li data-role="list-divider">Tweets</p></li>
          </ul>
        </div>
</div>

The tweet-list id shown in Listing 9–2 is our placeholder where we will append our Twitter search results. Twitter’s search API returns many data elements, however, we are only interested in the tweet text, the user that posted the tweet, and the user’s profile image.

TIP: To view all the data elements that are available from Twitter’s search API, launch this string in your browser “http://search.twitter.com/search.json?q=xmen”. This is the basic search API where the value of the “q” parameter is our searchable keyword(s). In this case, we are searching Twitter for any tweets with the keyword “xmen” in them.

TIP: Most browsers show JSON responses in an unformatted style that can be very unfriendly:

images

As an alternative, Firefox has a JSON Viewer plug-in4 that formats JSON responses in a more structured format:

images

Also, if you need to validate JSON, JSONLint5 can be a helpful tool.

jQuery Mobile has Ajax support built-in and this makes RESTful integrations simpler with no dependencies on third party JavaScript frameworks. This support comes from the jQuery API6 that jQuery Mobile extends. In jQuery, the $.ajax7 API is the preferred solution for RESTful integrations because of its simplicity and its flexible configuration options (timeout, caching, etc.).

__________

4 See https://addons.mozilla.org/en-US/firefox/addon/jsonview/.

5 See http://jsonlint.com/.

6 See http://jquery.com/.

7 See http://api.jquery.com/jQuery.ajax/.

To integrate jQuery Mobile with Twitter’s RESTful API, the following steps are necessary (see Listing 9–3):

  1. When the Twitter button is clicked, we will initially display the jQuery Mobile activity indicator so the user is visually aware that an activity is being processed in the background:$( "#twitterBtn" ).bind( "click", function(e) {
        $.mobile.showPageLoadingMsg();
  2. Next, we will load our Twitter results page into the DOM of the current page. If the page already exists in the DOM we will reload and update the cached page:$.mobile.loadPage("twitter.html", { reloadPage: true });
  3. Before our Twitter page is enhanced, we will send an AJAX request to the Twitter API to gather our search results:$(“#twitterPage”).live("pagebeforecreate", function(){
       $.ajax({...
  4. Our url option is configured to Twitter’s RESTful API and our search query is configured to find all tweets containing the keyword “xmen”:url: "http://search.twitter.com/search.json?q=xmen"
  5. Since the Twitter API exists on another domain, we are required to set our dataType option to jsonp. Normally, cross-domain communication is not allowed on the Web but JSONP8 helps facilitate a trusted means of integration across domains:dataType: "jsonp"
  6. Lastly, we implement our success callback to iterate the search results, create a list item for each row, and append the new markup to our list container:

success: function( response ) {...

Listing 9–3. Client-side Twitter integration (ch9/twitter.js)$( "#reviewsPage" ).live( "pageinit", function(){
    $( "#twitterBtn" ).bind( "click", function(e) {
        $.mobile.showPageLoadingMsg();

        // Reload Twitter results page even if it's already in the DOM
        $.mobile.loadPage("twitter.html", { reloadPage: true });

        // Prevent default click behavior
        return false;
    });
});

$( #twitterPage" ).live("pagebeforecreate", function(){
   $.ajax({
      url: "http://search.twitter.com/search.json?q=xmen",
      dataType: "jsonp",
      success: function( response ) {
         // Generate a list item for each tweet
         var markup = "";
         $.each(response.results, function(index, result) {
             var $template = $('<div><li><img class="ui-li-icon profile">
<p class="from"></p><p class="tweet"></p></li></div>');
             $template.find(".from").append(result.from_user);
             $template.find(".tweet").append(result.text);
             $template.find(".profile")
                          .attr("src", result.profile_image_url);
             markup += $template.html();
         });

         // Append the Tweet items into our Tweet list and refresh the
         // entire list.

         $( "#tweet-list" ).append(markup).listview( "refresh", true );

         // Transition to the Twitter results page.
         $.mobile.changePage( $("#twitterPage") );
      },
   });
});
In this example, we have chosen to load the Twitter results on demand when the user
clicks on the Twitter button. Alternatively, you may pre-fetch the Twitter data so users
can see the Twitter results instantly when the button is clicked. To set up this
strategy, add the data-prefetch attribute on the Twitter button:
<a href="twitter.html" id="twitterBtn" class="ui-btn-right" data-icon="custom" data-
iconpos="notext" data-prefetch></a>

__________

8 See http://en.wikipedia.org/wiki/JSONP.

Now the page change can be handled by the button’s default click behavior allowing us to remove our custom click handler for this button and the $.mobile.changePage() call after the Twitter results are appended to the list.

Also, in a production use case, you will want to configure the timeout and error callback on the $.ajax method to handle any unresponsive or unavailable API’s. For instance, if the Twitter API is unresponsive it may be helpful to notify the user:

timeout: 6000, // Timeout after 6 seconds
error: function(jqXHR, textStatus, errorThrown) {
    $.mobile.hidePageLoadingMsg();

    // Show error message
    $( "<div class='ui-loader ui-overlay-shadow ui-body-e
     ui-corner-all'><h1>"+ $.mobile.pageLoadErrorMessage +"</h1></div>" )
        .css({ "display": "block", "opacity": 0.96, "top": 100 })
        .appendTo( $.mobile.pageContainer )
        .delay( 800 )
        .fadeOut( 1000, function() {
            $( this ).remove();
        });
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *