The Observer Pattern
The Observer Pattern defines a one-to-many dependency between objects so that when one object (the Observee) changes state, all its dependents (the Observers) are notified and updated automatically. Most literature refers to the Observee as the Subject. For this article I've used the term "Observee" to emphasize the role of this objectit's the object responsible for downloading the news. The Observers are the objects interested in receiving the news.
ContentRetriever use a helper class, HtmlBuilder, to parse the retrieved JSON text and build the HTML code to be displayed within a marquee HTML element. This helper class isolates the presentation logic. If you wanted to change the news format you would need to modify only the logic in HtmlBuilder. The sample application uses a CSS stylesheet to define the fonts, colors and so on, which you can modify it according to your taste.
Here's the ContentRetriever class constructor:
function ContentRetriever(jsonDataRetriever, observerObjectsArray)
// JSON data retrieved and parsed
this.jsonData = "";
// URL of the Server-side component responsible
// for retrieving the JSON data
this.jsonDataRetriever = jsonDataRetriever;
// AJAX object
this.ajaxObj = createHttpRequest();
// array of observers
this.observerObjectsArray = observerObjectsArray;
The first parameter is a URL that points to the server-side component responsible for retrieving the news. The second parameter is an array of objects (observers) interested in being notified when the information gets retrieved by ContentRetriever (the observee). After all, this is the essence of the Observer Pattern: something doing a job and others just sitting around waiting to be notified when it's done! The function createHttpRequest
creates an XMLHttpRequest object, taking browser differences into account. This function is defined within the ajax.js file that you can find in the downloadable code
for this article. The file demo.htm
var marquee = new Marquee("newsMarquee", 2, true);
var contentRetriever = new ContentRetriever(
//get the content
The preceding code creates an instance of the Marquee class, which I'll discuss shortly, and then builds a ContentRetriever object, passing in both the URL of the PHP script responsible for retrieving the data and an array of observer objectsin this case just one.
Here's the code of the Marquee constructor:
function Marquee(elemId, scrollamount, stopOnMouseOver)
this.elemId = elemId;
this.scrollamount = scrollamount;
this.stopOnMouseOver = stopOnMouseOver;
this.dataArray = ;
this.errorMessage = "No news available";
The Marquee constructor takes three parameters:
- elemIdThis is the id of the div element apt to display the news.
- scrollamountThe scrollamount attribute of the marquee HTML element. It indicates the scrolling speed.
- stopOnMouseOverA Boolean indicating whether news scrolling should be stopped when the user hovers the mouse over a news item.
property is the array containing the news items retrieved and parsed, and the errorMessage
property is an error message to display if the news download fails.
The method that actually retrieves the news is getContent()
, in the ContentRetriever class. Here's the code:
ContentRetriever.prototype.getContent = function()
var instance = this;
this.ajaxObj.open('GET', this.jsonDataRetriever, true);
checks whether the XMLHttpRequest object was created correctly. Then it prepares an AJAX call using the HTTP GET
method, the URL for the PHP news-retrieval script, and a Boolean specifying whether the call should be asynchronous (the third parameter (true
) of the open()
call). Because the call is asynchronous you must define a callback function that will execute when the call completes; in this case, that's processDataRetrieved
. Lastly it sends the AJAX call without any other data (using null
as the argument of send()
The server-side script that retrieves the actual datathe file tickerDataRetriever.php
is very simple:
$NEWS_FOLDER = "news";
$filename = "news.txt";
//name of the news file
$localFile = $NEWS_FOLDER . "/" . $filename;
//return the content as a JSON string
For simplicity's sake, the news in JSON format was hard-coded within a text file. Of course, in a real world application, the information would be retrieved from a database, an RSS feed or whatever you might choose for dynamic content. In this case, the PHP script just retrieves the JSON text and passes it back to ContentRetriever. This is the content of news.txt:
"title" : "This is the first item's title",
"link" : "http://www.alessandrolacava.com",
"description" : "This is the description of the \"first\" news.
The link takes you to my Web site"
"title" : "Second item's title",
"link" : "http://www.json.org",
"description" : "You can appreciate how easily you
can parse JSON text. This link takes you to the JSON Web site"
"title" : "This is the third item's title.",
"link" : "http://www.devx.com",
"The link for this item takes you to the DevX Web site"
As you can see, the file content is just a JSON string representing an array of objects. Each object represents a news item and has three properties: title
. Notice the escaped double quotes (\"
) in the first item's description
value. You must escape embedded double quotes; otherwise the parser will interpret them as the end of the field value. At the end of the article you'll see how to automate this process when retrieving dynamic content.
The following function processes the retrieved content (the JSON text):
ContentRetriever.prototype.processDataRetrieved = function()
if (this.ajaxObj.readyState == 4)
//check whether the response is empty
if(this.ajaxObj.responseText != null &&
this.ajaxObj.responseText.length > 0)
var htmlBuilder = new HtmlBuilder(this.ajaxObj.responseText);
//parse the JSON data
this.jsonData = htmlBuilder.getHtml();
//return a zero-length array if an error occurs
this.jsonData = ;
// notify observers
The preceding code first checks if the request completed successfully. Then it instantiates an HtmlBuilder object, passing in the JSON text. The HtmlBuilder's getHtml
method parses the JSON string and builds the HTML code to be displayed within the marquee. When it's done, it calls the notify
//notify all observers
ContentRetriever.prototype.notify = function()
//call the observers' callback function, passing in the resulting array
for(var i = 0; i < this.observerObjectsArray.length; i++)
The notify method calls the update
method of all the subscribed observersin this case just one, the marquee.
The HtmlBuilder getHtml
function does the transformation work of creating HTML from the returned JSON code:
HtmlBuilder.prototype.getHtml = function()
var ret = ;
//decode the JSON text
var obj = this.decodeJson();
//get the array
var items = obj.items;
//build the HTML code using the array
for(var i = 0; i < items.length; i++)
var item = "";
//build the title
item += this.buildTitle(items[i]);
item += "<br />";
//build the description
item += this.buildDescription(items[i]);
item += "<br />";
HtmlBuilder.prototype.decodeJson = function()
return eval("(" + this.jsonString + ")");
As you can see it takes just one
The rest of getHtml
just formats the news conveniently and creates an array of news items. This array is the parameter passed to the update
method of Marquee that displays the news within a marquee HTML element.