Tips for debugging Ajax applications

Developing Asynchronous JavaScriptTM And XML (Ajax) applications, whether you use pre-existing toolkits such as the Dojo Toolkit or develop everything from scratch, can introduce challenges.  The challenges typically arise from two main issues.

This topic summarizes typical errors and how you can use available tools to debug them.  This section is not intended as an all-encompassing debugging guide for JavaScript errors.

Debugging issue 1:   No compiler syntax checking

If you have written a custom widget similar to the following example on the Dojo Toolkit, you can get errors reported in tools such as Firebug; for example:

Could not create widgets in dijit_layout_ContentPane_2 from templates/tabs.html Error: Could not load class 'foo.Bar'. Did you spell the name correctly and use a full path, like 'dijit.form.Button'?

The message does not explain the problem, only that it did not load a particular widget.  This error can be caused by multiple programming errors; however, the most common ones are syntax errors in the widget JavaScript.   The following most common syntax errors cause the previous error:
  • Using a semicolon instead of a comma when separating attributes of a JavaScript object definition.  This error is common for novice JavaScript developers who have a background in Java or C++ language. 
    • All Dojo Toolkit widgets and extension widgets are JavaScript objects, and therefore, any custom widgets must use the correct comma separator between properties of the object, which include function declarations as properties.
  • Incorrectly ending the last attribute definition in a JavaScript object definition with a comma.  The last property in any JavaScript object definition must not end with a comma.
  • Malformed (unmatched) {} closures.
  • Malformed function definitions.
  You can avoid syntax errors by running a lint processor that understands JavaScript syntax on your code as you develop it.  The lint processor checks for syntax errors before the code is run.  Some of the JavaScript lint processors available on the Web include:  http://www.jslint.com/   and   http://www.aptana.org/.   IBM does not control, develop, endorse or warranty the referenced lint Web programs; the links are provided as example references. 

Most lint processors identify the previous errors and more.  Many of the lint processors also enforce that JavaScript program statements typically end each line with a semicolon.  While ending with a semicolon is considered optional in JavaScript, it is highly recommended to use for strictness and uniformity. 

In summary, using lint syntax checking saves development time when trying to find the misplaced comma, malformed function, or missing closure.

Debugging issue 2:   Runtime problems

Assuming that all the syntactical errors were caught by running a lint on the JavaScript code and corrected, the next set of problems are all related to runtime problems.   These issues are more complex to debug, as the various browsers do not report errors in the same way.  Therefore, as a JavaScript developer, you must become familiar with debugging tools and browser error reporting mechanisms that are specific to each of the major supported browsers on which your application is used. The following list outlines how some of the more well-known browsers report errors:
  • Microsoft Internet Explorer:  Errors, such as accessing an undefined reference, are reported as messages from the browser with the line number and a simple description of the error.
  • Firefox 1.5.X - 2.0.X:  The Firefox browsers report all JavaScript errors into a 'JavaScript Console'.  On a page that encountered JavaScript problems, the Web application fails, and the cause of the failure is not obvious.  Therefore, while you are developing and testing, use these browsers to regularly open and check the JavaScript console.  This console can be located from the following menu:  
    • Firefox 1.5.X - 2.0.X:  Tools->JavaScript console.

The most common errors encountered at run time tend to be:
  • Referencing undefined variables.  For example, trying to access an attribute on a currently undefined object, such as jsObject.someAttribute, where the jsObject variable has not been assigned.
  • Functions defined on a JavaScript object accessing properties on that JavaScript object and failing to use the this reference identifier,  for example:
    Incorrect:
    <HEAD>
    <SCRIPT>
    function testOnload() {
    var fooObject = {
    fooAttribute: "This is foo",
    fooFunction: function() {
    alert("The value of foo is: [" + fooAttribute + "]");
    }
    };
    fooObject.fooFunction();
    }
    window.onload=testOnload;
    </SCRIPT>
    </HEAD>
    <HTML>
    </HTML>


    Correct:
    <HEAD>
    <SCRIPT>
    function testOnload() {
    var fooObject = {
    fooAttribute: "This is foo",
    fooFunction: function() {
    alert("The value of foo is: [" + this.fooAttribute + "]");
    }
    };
    fooObject.fooFunction();
    }
    window.onload=testOnload;
    </SCRIPT>
    </HEAD>
    <HTML>
    </HTML>



The following references are provided as Web documentation available to the public on debugging general Ajax errors.  Any references in this information to non-IBM Web sites are provided for convenience only and do not in any way serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM® product and use of those Web sites is at your own risk.    

Debugging references:
Debugging tools: