Putting XMLHttpRequest into a Factory

an article added by: Sonja Lande at 05312007


AJAX :: Putting XMLHttpRequest into a Factory ::

 French | Spanish | Portuguese | Italian | German | Japanese | Chinese | Korean | Russian | Arabic Bookmark and Share

Managing Runtime Behavioral Code

Problem You want to effectively manage and debug your runtime behavioral code. Theory Using the eval keyword or dynamically assigning functions to object properties is a big part of dynamic programming. Dynamic programming involves code that exhibits a behavior at runtime, or behavioral code. Behavioral code is not a bad idea, but it does make for more complicated debugging. The main problem with behavioral code is that the debugger has no idea what source it is debugging. Solution There are several solutions you can consider here they are in brief:

• Implement test-driven development and perform in-depth testing in an incremental manner. Doing otherwise will cause errors to be generated in code pieces that do not have problems. Throughout this article, recipes use test-driven development techniques that you can inspect to understand how the code works. I highly advise that you take a moment now to explore how code is written, if you have not already done so. Take a look at these files, for example: /website/ROOT/ajaxrecipes/javascript/conventions.html, /website/ROOT/ajaxrecipes/javascript/proxy.html, and /website/ROOT/ajaxrecipes/ javascript/variablebehavior.html.

• Generate the code into a buffer that is dumped to the HTML page text box. Take the dumped code and paste it into an HTML page for execution. The dumped code will contain the error that can be debugged. This solution is only advisable, however, if you are having persistent problems and cannot find the source.

• Use simple principles. I like dynamic and generated code as much as anybody else, but I stay away from code that is too clever and tries to solve too many problems at once. For example, I typically write verbose code and do not combine multiple operators into a single statement.

• Use a debugger. Mozilla and Firefox have fairly decent debuggers, and you should use them. With Microsoft Visual Studio 2005, it is possible to debug very complicated JavaScript code.

Putting XMLHttpRequest into a Factory

You want to put XMLHttpRequest into a factory. Theory When you are using XMLHttpRequest, the problem is how to instantiate XMLHttpRequest. Each browser has a different way of instantiating XMLHttpRequest. Here is what Mozilla and most other browsers use (this code will also work in Internet Explorer starting with version 7): var xmlhttp = new XMLHttpRequest(); You use the following source code for Internet Explorer versions before 7: var xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); The Microsoft.XMLHTTP buffer is a general identifier, as there are specializations available depending on the browser. Solution The short answer to the problem is that to instantiate XMLHttpRequest you need to use different techniques on different browsers. To be able to instantiate the XMLHttpRequest object, you need to create an abstraction. The abstraction could be a class or a function, but which you choose does not matter. What does matter is that you create an abstraction or implement the Factory pattern.1 In the Factory pattern implementation, the main challenge is to identify which browser is executing the script and then use the appropriate XMLHttpRequest instantiation. The libraries jsolait, Prototype, Yahoo! patterns, and Dojo Toolkit all implement an XMLHttpRequest abstraction that is coded in the same manner. To illustrate the gist of how it is coded consider the following source code, which is from the Yahoo! Design Pattern Library (http://developer.yahoo.com/ypatterns).

    createXhrObject:function(transactionId)
    {
    var obj,http;
    try
    {
    // Instantiates XMLHttpRequest in non-IE  browsers and assigns to http.
    http  = new XMLHttpRequest();
    // Object literal with http and id properties
    obj = { conn:http, tId:transactionId };
    }
    catch(e)
    {
    for(var i=0; i<this._msxml_progid.length;  ++i){
    try
    {
    // Instantiates XMLHttpRequest for IE and  assign to http.
    http  = new ActiveXObject(this._msxml_progid[i]);
    // Object literal with http and id properties
    obj = { conn:http, tId:transactionId };
    }
    catch(e){}
    }
    }
    finally
    {
    return obj;
    }
 },

The instantiations are wrapped in a series of try and catch blocks. A try and catch block in JavaScript is an exception block. The idea behind this form of abstraction is that you try executing some source code, and if it fails you do something else. The following steps are carried out in the source code:

1. Enter the first exception block.

2. Execute the XMLHttpRequest instantiation using the new keyword.

3. If the instantiation works, then the finally block is reached.

4. If the instantiation fails, an exception is generated and the catch block starts a loop.

5. The loop attempts to instantiate the Internet Explorer XMLHttpRequest using different identifiers referenced by the this._msxml_progid data member.

6. If the XMLHttpRequest object cannot be instantiated, an empty catch block captures the exception.

7. Regardless of what happens, the finally block is executed and returns the object instance stored in the obj variable. The main idea of the abstraction is to execute the code, and if the browser does not support the functionality, an exception is generated. The exception is caught and causes a different instantiation sequence to start. What troubles me about this code is that it does not attempt to figure out what is supported, but uses JavaScript exceptions. As the implementation stands, an exception is generated for amajority of cases. This is because at the time of this writing, Internet Explorer has a market share greater than 80%. This means that attempting to instantiate XMLHttpRequest using the new keyword will not work and will generate an exception. The alternate way of instantiating XMLHttpRequest is used by the library Jaxson, as outlined in the articles Ajax in Action (Manning, 2005) and Professional Ajax (Wrox, 2006). The technique shown in Ajax in Action is perfect2 and is implemented by Jaxson as follows.

    Source: /website/ROOT/scripts/communications.js
    if( window.ActiveXObject) {
    FactoryXMLHttpRequest = function() {
    return new ActiveXObject(  "Microsoft.XMLHTTP");
    }
    else if( window.XMLHttpRequest) {
    FactoryXMLHttpRequest = function() {
    return new XMLHttpRequest();
    }
 }
 throw new Error( "Could not instantiate  XMLHttpRequest");

The FactoryXMLHttpRequest function is different in that it is assigned as the page is being loaded by the browser. The advantage of assigning the FactoryXMLHttpRequest method is that you don’t need to make yet another decision via a decision structure. You are defining the behavior of the program during the initialization of the HTML page; you are not constantly asking what the behavior should be. This reasoning is also shown in Recipes 2-4 and 2-7. Think about the context. If you are loading a page in a browser, do you think you could, for some reason or another, move your executing code to a completely different browser after it’s been loaded and executed? The answer is no, because it is physically impossible. The browser you used to load the page will not during the execution decide to run the already processed code elsewhere. In the initialization, the decision tests for the existence of the window.ActiveXObject or window.XMLHttpRequest property. The decision is asking the browser if specific types exist, and if they do, then they can be instantiated. This is a better approach than performing an instantiation and waiting for a potential exception, because the code knows what the browser is capable of and asks for the functionality. If the functionality does not exist, then an exception is generated by instantiating the Error type. This is a valid use of using an exception; at the time of this writing, you have only two ways to instantiate the XMLHttpRequest object. You may be thinking, “But what if the browser does not support Ajax and the XMLHttpRequest object?” If the browser does not support Ajax, the FactoryXMLHttpRequest function should not be called. The Permutations pattern and recipes in Article 3 address these issues.

Note To instantiate the XMLHttpRequest object on Internet Explorer, a single line of source code is used. In contrast, other libraries use multiple instantiation attempts. These multiple instantiation attempts are not required because, per the MSDN documentation, it is only necessary to use the Microsoft.XMLHTTP string in Internet Explorer version 6 and below. When instantiating the XMLHttpRequest object, keep the following points in mind:

• You will need to use an abstraction, because people will continue to use older versions of Internet Explorer for some time to come. Thus, you’ll still have a need to figure out which instantiation technique to use.

• You should not use exceptions to test for expected functionality. Doing so without thinking will cause exceptions to be hidden.

• The better approach is to test for functionality and then instantiate the XMLHttpRequest instance.

• All that said, if you use a predefined instantiation that uses exceptions, such as the Yahoo! Design Pattern Library, it’s not the end of the world. The point of this recipe is to suggest a better approach to use whenever possible.

legal disclaimer

Our website is not responsible for the information contained by this article. Web-articles is a free articles resource.
Suggestion: If you need fresh, daily updated content for your website, feel free to use our service. Click here for more information.

related articles

1. Understanding the Definition and Philosophy of Ajax
The focus of this article is to provide solutions to some common, general problems and questions that are bound to arise before or during development of Asynchronous JavaScript and XML (Ajax) and Representational State Transfer (REST) applications. These common questions are not always technical in nature, often leaning more toward theory or philosophy of development. The problem with these kinds of questions is that once you begin to think about them, you keep going in a circle and end up where you star...

2. Understanding the Definition and Philosophy of Web Services and SOA
Understanding the Definition and Philosophy of Web Services and SOA Wikipedia offers the following definition of Web services:4 The W3C defines aWeb service as a software system designed to support interoperable machine-to-machine interaction over a network. This definition encompasses many different systems, but in common usage the term refers to those services that use SOAPformatted XML envelopes and have their interfaces described by WSDL. For ex...

3. Understanding the Definition and Philosophy of REST
Understanding the Definition and Philosophy of REST REST is a controversial topic among Web service enthusiasts, because it’s considered to stand for the opposite of what Web services and SOA are trying to achieve. The problem with this thinking is that REST is not in contradiction with the abstract definition of SOA and Web services. REST is in contradiction with technologies such as SOAP, WSDL, and WS-* specifications. The following offers a quick definition of REST:...

4. The Easiest Way to Get Started with Ajax and REST
The Easiest Way to Get Started with Ajax and REST Problem You want to know the best way to get started with writing Ajax and REST. Solution When developing an Ajax and REST application, you must decide on the tools and frameworks you’ll use. The choice is simple: Use whatever you’re using today, and write some Ajax applications. You don’t need to change the tools you’re using today. Whether you’re using ASP.NET, JavaServer Pages (JSP), PHP, Ruby, or Python, you...

5. Testing a Dynamic Contract with Ajax
Coding the Contract Using Test-Driven Development Techniques Coding the contract using agile and test-driven development techniques requires writing a number of tests and implementing aMock URL layer. Problem You want to code the contract using these development techniques. Solution To demonstrate, let’s define a use case, implement the use case as a contract, write a test case(s) to implement the contract, implement the contract in the Mock URL, and finally...

6. Testing the Client Side Logic
Problem You want to effectively test your application’s client-side logic. Theory Testing GUI code tends not to be a productive task because of the complications that arise. The main complication is how to test the correctness of a user interface. Imagine a situation where clicking a button causes a table to be filled with data. Now imagine that when a check box is checked and the button is clicked again, a different table is filled with content. The fact that clicking the same button results in two ...

7. Understanding JavaScript and Types
Understanding JavaScript and Types Problem You want to work around the fact that JavaScript does not have types declared for its variables. Theory JavaScript code does not have any variables with a declared type. The lack of typed variables is apparent when you declare functions. That said, not having typed variable declarations does not mean JavaScript has no types or no type safety. Let’s start out with the simple declaration of a function, as illustrated by the following ex...