Implement a Twitter service to fetch data from Twitter.
The TwitterService
object that fetches data from Twitter is located in the TwitterService.js
file. A REST (Representational State Transfer) API call is created by constructing a URL with the appropriate Twitter method name and parameters. The credentials are encoded in the URL to log users into Twitter automatically. A JSON (JavaScript Object Notation) response is requested and the maximum number of returned responses is set. The URL is passed to the _doRequest
function.
TwitterService.prototype.getFriendsTweets = function( count, progressId ) { // Build URL and do the request. var url = "http://" + this.username + ":" + this.password + "@twitter.com/statuses/friends_timeline.json?count=" + count; this._doRequest( url ); }
The _doRequest
function makes an asynchronous request to the URL. The function also sets the type of the request to GET or POST. Before making the actual request by calling the XMLHttpRequest send
function a function is assigned to the XMLHttpRequest readystatechange
event handler.
TwitterService.prototype._doRequest = function( url, type ){ this.httpReq = new XMLHttpRequest(); var self = this; this.httpReq.onreadystatechange = function() { self._readyStateChanged(); }; // Default to GET HTTP request if none is provided. if ( type == null ) { type = "GET"; } this.httpReq.open( type, url, true ); this.httpReq.send( "" ); }
The _readyStateChanged
function is the heart of the TwitterService
. The readystatechange
event is not only triggered when the request is complete so whenever the event handler function gets called, the value of the XMLHttpRequest readyState
property must be checked. Value 4 (DONE) indicates that the data transfer has been completed or that something went wrong during the transfer. Because it indicates both successful and unsuccessful requests, the response status of the request must be determined by looking at the status
property of the XMLHttpRequest. If the value is 200 (OK), the response text is retrieved from the XMLHttpRequest responseText
property. Any other value indicates that an error has occurred during the request.
TwitterService.prototype._readyStateChanged = function() { // complete request? if ( this.httpReq.readyState == 4 ) { // attempt to get response status var responseStatus = null; try { responseStatus = this.httpReq.status; } catch (noStatusException) { alert( StringTable.Code.twitterServiceNoStatusAlert ); } // Check response status. if ( responseStatus == 200 ) { var res = null; // If response doesn't contain xml, forward text. res = this.httpReq.responseText; // Not needed anymore. this.httpReq = null; this.handleSuccessResponse.call( this, res ); } else { this.handleErrorResponse.call( this, responseStatus ); } } }
Depending on the response status of the request, either handleSuccessResponse
or handleErrorResponse
is triggered to notify whoever triggered the request. Since this is all done asynchronously, callback functions are used.
TwitterService.prototype.handleSuccessResponse = function( arg ) { // Eval the data. var response = eval( "(" + arg + ")" ); // Feed fetched and parsed successfully. if ( this.onSuccess ) this.onSuccess.call( this, response ); } TwitterService.prototype.handleErrorResponse = function( status ) { if ( this.onError ) this.onError.call( this, status ); }
If onSuccess
or onError
functions are defined, they are called with a response object. For an error response, this object is an integer that indicates the status of the request. For a successful response, before triggering the onSuccess
callback, an eval
is performed on the response text. This creates JavaScript objects from JSON response text into the response variable, which is then passed as a parameter to the onSuccess
callback.