Debugging Dojo: Common Error Messages

By on October 31, 2012 3:37 pm

Debugging JavaScript can be a tedious and frustrating chore. To compound the already difficult task of debugging, browser vendors each have their own style of error messaging, some of which are confusing, cryptic, or downright misleading to the untrained eye. Through the delivery of our Dojo workshops, we’ve observed a number of common mistakes that are easy to fix once you decipher the error message. Take some time to familiarize yourself with the following common errors that appear when working with Dojo, their symptoms, and their solutions. With this knowledge, writing manageable code is not only possible, but a lot less cryptic.

Issue: Missing Parameter

What you’re likely to see in your debugging environment

  • Firefox + Firebug
  • ReferenceError: on is not defined

  • Chrome
  • Uncaught ReferenceError: on is not defined

  • Internet Explorer 9
  • The value of the property ‘on’ is null or undefined, not a Function object

Possible Cause

You are missing a module parameter in the callback function of require. As you can see in the example, we list dojo/on as a dependency, but forget to specify it as a parameter to our callback function. As such, whenever we attempt to reference it, it fails because it is undefined.

	require(["dojo/dom", "dojo/on"], function (dom) {
		on(dom.byId("button"), "click", function (e) {
			console.log("My button was clicked!");
		});
	});
	

Solution

Ensure you specify a callback parameter for each module that you’re including to which you will need locally scoped access. If you’re getting a ReferenceError or “not a Function”, chances are, you missed a parameter.

Issue: Callback Parameter Mismatch

What you’re likely to see in your debugging environment

  • Firefox + Firebug
  • TypeError: dom.byId is not a function

  • Chrome
  • Uncaught TypeError: Object function has no method ‘byId’

  • Internet Explorer 9
  • Object doesn’t support property or method ‘byId’

Possible Cause

The callback parameter order does not match the dependency order. As you can see in the code, we require our dependencies in the order of dojo/dom and then dojo/on; however, in our callback, we have them in the order of dojo/on and then dojo/dom. Dojo does not magically know that dojo/on is mapped to the local variable on; it simply maps the returned factory function from dojo/on to the local variable specified in the given order. As written, the example makes our on variable actually reference the dojo/dom module and vice versa.

	require(["dojo/dom", "dojo/on"], function (on, dom) {
		on(dom.byId("button"), "click", function (e) {
			console.log("My button was clicked!");
		});
	});
	

Solution

Make sure your callback parameters match up to the order of your dependency list in require or define.

Issue: Wrong dojo path

What you’re likely to see in your debugging environment

  • Firefox + Firebug
  • ReferenceError: require is not defined

  • Chrome
  • Uncaught ReferenceError: require is not defined

  • Internet Explorer 9
  • ‘require’ is undefined

Possible Cause

The path to your dojo.js file is incorrect.

		<script src="incorrect/path/to/dojo.js"></script>
	

Solution

Ensure the URL in the src of your script is the correct path to dojo.js

Issue: Incorrect package path

What you’re likely to see in your debugging environment

  • Firefox + Firebug
  • Error: xhrFailed

  • Chrome
  • GET incorrectPackage/myModule.js 404 (Not Found)

  • Internet Explorer 9*
  • * IE9 will not show an error in the JavaScript console, your code will simply just fail. In order to see the 404, you have to go to the “Network” tab and click “Start Capturing”.

    * The Dojo Loader will also pass the number 3 to the callback in place of the module. 3 is the Dojo AMD loader code for attempting to load a non-module.

Possible Cause

The package you are referencing has an incorrect path. This can happen when using an incorrect MID (module identifier) as a dependency or when a package is configured incorrectly in your dojoConfig.

	require(["incorrectPackagePath/myModule"], function (myModule) {
		myModule.doSomething();
	});
	
	var dojoConfig = {
	    packages: [{
	        name: "myPackage",
	        location: "incorrect/path/to/myPackage"
	    }]
	};
	

Solution

Ensure you are using the correct paths to your packages. If you are getting a non-module error, this is the most common reason why.

Issue: Forgot dojo/query with Event Delegation

What you’re likely to see in your debugging environment

  • Firefox + Firebug
  • TypeError: matchesTarget is undefined

  • Chrome
  • Uncaught TypeError: Cannot call method ‘matches’ of undefined

  • Internet Explorer 9
  • Unable to get value of the property ‘matches’: object is null or undefined

Possible Cause

Using event delegation with dojo/on and forgetting to pull in dojo/query. To keep dojo/on as lightweight as possible, it does not automatically pull in dojo/query. Because of this, it does not have the capability to perform event delegation by default.

	require(["dojo/on"], function (on) {
		on(document.getElementById("myContainer"), "button:click", function (e) {
			console.log("A button was clicked!");
		});
	});
	

Solution

Ensure that you pull in dojo/query when you need to use event delegation with dojo/on.

Issue: Forgot handleAs for dojo/request

What you’re likely to see in your debugging environment

  • Firefox + Firebug
  • data.getElementsByTagName is not a function

    XML

    JSON*

  • Chrome
  • TypeError: undefined method

    XML

    JSON*

  • Internet Explorer 9
  • TypeError: Object doesn’t support property or method ‘getElementsByTagName’

    XML

    JSON

    * Notice how the data is parsed as a string, which makes the data[0] return as the first letter in that string, instead of the first element in what would be an array

Possible Cause

You have forgotten to set the handleAs property for dojo/request. When you do this, whatever value is returned is passed to the Deferred.resolve as plain text. This can cause issues if you’re expecting the data to be a JSON object or an XML document.

	require(["dojo/request"], function (request) {
		request("test.xml").then(function (data) {
			console.log(data.getElementsByTagName("name"));
		});
	});
	
	require(["dojo/request"], function (request) {
		request("states.json").then(function (states) {
			console.log("The first state object is", states[0]);
		});
	});
	

Solution

Ensure you use the handleAs property of the options object when using dojo/request.

Issue: Loop Bound Events

What you are experiencing

Events that fire all have the same value, or point to the same event handler.

Possible Cause

You used a loop to bind event handlers, and the final value in the loop is being referenced by the event handlers due to JavaScript’s closures. This will cause the same value to be referenced by all event handlers that were bound in the loop.

	require(["dojo/on"], function (on) {
		for (var i = 0, list = document.getElementById("list"), item; i < 5; i++) {
			item = document.createElement("li");
			item.innerHTML = "List item #" + i;
			on(item, "click", function () {
				alert(i);
			});
			list.appendChild(item);
		}
	});
	

How to fix it

You can create an event handler factory, or iterate over the items to add handlers using a forEach.

	function createHandler(value) {
		return function () {
			alert(value);
		};
	}
	require(["dojo/on"], function (on) {
		for (var i = 0, list = document.getElementById("list"), item; i < 5; i++) {
			item = document.createElement("li");
			item.innerHTML = "List item #" + i;
			on(item, "click", createHandler);
			item.onclick = createHandler(i);
			list.appendChild(item);
		}
	});
	

If you're iterating over items, you can use dojo/_base/array.forEach

	require(["dojo/_base/array", "dojo/on"], function (arrayUtil, on) {
		var list = document.getElementById("list"),
			myArray = [0, 1, 2, 3, 4],
			item;

		arrayUtil.forEach(myArray, function (value) {
			item = document.createElement("li");
			item.innerHTML = "List item #" + value;
			on(item, "click", function () {
				alert(value);
			});
			list.appendChild(item);
		});
	});

	

You can use event delegation.

	require(["dojo/on", "dojo/query"], function (on) {
		on(document.getElementById("myContainer"), "button:click", function (e) {
			console.log("I was clicked!", e.target);
		});
	});
	

Issue: Forgot to Call startup

What you are experiencing

A Dijit does not appear to initialize fully.

Possible Cause

You forgot to call startup on the Dijit.

		<div id="container"></div>
	
	require(["dijit/layout/BorderContainer", "dijit/layout/ContentPane"], function (BorderContainer, ContentPane) {
		var container = new BorderContainer({
			design: "sidebar",
			gutters: true,
			liveSplitters: true
		}, "container"),
		leftPane = new ContentPane({
			splitter: true,
			region: "left",
			innerHTML: "Left Pane"
		}),
		centerPane = new ContentPane({
			splitter: true,
			region: "center",
			innerHTML: "Center Pane"
		});
		
		container.addChild(leftPane);
		container.addChild(centerPane);
	});
	

What it looks like

Without startup

With startup

Solution

Ensure you're calling startup on widgets that are created programmatically. This is especially true for layout widgets.

Issue: Forgot dojo/domReady!

What you're likely to see in your debugging environment

  • Firefox + Firebug
  • TypeError: document.musicPrefs is undefined

  • Chrome
  • Uncaught TypeError: Cannot read property 'other' of undefined

  • Internet Explorer 9
  • Unable to get value of the property 'other': object is null or undefined

Possible Cause

You have forgotten to use dojo/domReady!. dojo/domReady! waits until the DOM is ready to be manipulated before the require callback is executed.

	<script>
		document.musicPrefs.other.value = "Afrobeat";
	</script>
	<form name="musicPrefs">
		<input type="text" name="other" />
	</form>
	

Solution

If you need to interact with the DOM, use dojo/domReady! to ensure it's completely loaded before your code executes on it.

Issue: Forgot Theme CSS Class Name

What you are experiencing

Your widgets look unstyled.

What it looks like without class name

What it looks like with class name

Possible Cause

You have forgotten to put a theme class name on body tag. This class is necessary on the body tag because of the way that the CSS rules are set up.

	<body>
		<button>Click me!</button>
	</body>
	

Solution

Ensure you add the class name ("claro", "tundra", etc) of the theme to the body tag. This class is necessary on the body tag because of the way that Dijit's CSS rules are written.

Issue: Failed Resource Loading

What you're likely to see in your debugging environment

  • Firefox + Firebug
  • GET http://localhost/dojo/invalid/path 404 Not Found

  • Chrome
  • Failed to load resource: the server responded with a status of 404 (Not Found)

  • Internet Explorer 9*
  • * IE9 will not show an error in the JavaScript console, your code will simply just fail. In order to see the 404, you have to go to the "Network" tab and click "Start Capturing".

Possible Cause

Failed to load a resource via request. This can happen if the file is missing or if the URL is wrong. If you're using dojo/request/registry, you may have a provider set up incorrectly.

	require(["dojo/request"], function (request) {
		request("invalid/path");
	});
	

Solution

Ensure your requests are pointing to the right URL. If you're using dojo/request/registry, ensure that your provider is set up properly.

Issue: Load from the local File System

What you're likely to see in your debugging environment

  • Chrome
  • XMLHttpRequest cannot load file:///D:/xampp/htdocs/dojo/test.xml. Origin null is not allowed by Access-Control-Allow-Origin.

Possible Cause

Loaded file from file system and not web server.

Solution

Ensure you are loading a page using the web server (http:// or https://) and not the file system (file:///)

Issue: Trailing comma

What you're likely to see in your debugging environment

  • IE7 and before
  • Expected identifier, string or number

Possible Cause

Trailing comma in object literal. This is typically only an issue with IE7 and before, but is not valid, and should be avoided.

	var user = {
		name: "matt",
		email: "matt@email.com",
	};
	

Solution

Ensure you do not have trailing commas in your object literals.

Issue: Semicolon in Object Literal

What you're likely to see in your debugging environment

  • Firefox + Firebug
  • SyntaxError: missing } after property list

  • Chrome
  • Uncaught SyntaxError: Unexpected token ;

  • Internet Explorer 9
  • Expected '}'

Possible Cause

Used ';' instead of ',' in object literal.

	var user = {
		name: "matt";
		email: "matt@email.com"
	};
	

Solution

Ensure that you use a comma between properties in object literals.

Issue: define Already Defined

What you're likely to see in your debugging environment

  • Firefox + Firebug
  • defineAlreadyDefined

  • Chrome
  • defineAlreadyDefined

  • Internet Explorer 9
  • defineAlreadyDefined

Possible Cause

Including Dojo twice.

	    <script src="dojo.js"></script>
	    <script src="dojo.js"></script>
	

Solution

Ensure you are including Dojo only once.

Issue: Non-module module

What you're likely to see in your debugging environment

  • Firefox + Firebug
  • TypeError: myModule.init is not a function

  • Chrome
  • Uncaught TypeError: Object 3 has no method 'init'

  • Internet Explorer 9
  • Object doesn't support property or method 'init'

Possible Cause

You used require instead of define in your module definition. This will cause the module to be returned to your callback as "3", which is the Dojo loader error code for non-module.

	// Inside of your module
	require(["dojo/on"], function (on) {
	    return {
	        init: function () {
				on(this.buttonNode, "click", function () {
					this.submitForm();
				});
			}
	    };
	});
	

Solution

Ensure you are using define in your module definitions.

Conclusion

Troubleshooting some JavaScript and dojo errors can be tedious and frustrating, but knowing these common errors will help alleviate some of that stress. There are also tools, such as JSHint that can help you lint your code and provide a quick set of eyes to catch some of the errors that were outlined here. Also, learning how to use Firebug or the Developer Console can also help shave time off of your development and debugging process.

Our team thinks this list should become a living document of common error messages so, please submit suggestions in the comments and we'll incorporate them into this project in the future!

Getting Help

If you need assistance, SitePen delivers Dojo workshops, which range from an introduction to Dojo's core APIs, to more advanced workshop covering approaches to building desktop and mobile web user interfaces, and proper client-side application architecture. We also offer excellent JavaScript and Dojo support to help you work through any issues you may find. Contact us to discuss your project and how we can help.

Comments

  • Kitson Kelly

    Good article! One thing to point out about the “define Already Defined” error is that sometimes people will run into this with a build where the have built a bootable layer in addition to trying to load dojo/dojo.js.

  • Tried to register widget with id==* but that id is already registered
    this is familiar for novice dojo programmer.

  • Richard

    milad – you have either reused an id or (more likely) parsed the document twice. If your config has parseOnLoad:true, then make sure you aren’t calling parse anywhere else or using widgets programmatically. I have parseOnLoad:false, then load widgets by template or create them programmatically, and call startup() on them.

  • Another common pair of errors for people to new to AMD occurs by treating a module identifer as an absolute path, rather than relative to the loader’s base directory.

    By including a leading / and full path to a module, or including a protocol, or a .js at the end, the loader looks for a non-AMD JS file to load. One form of this error occurs when including the leading /, but which leads to an unexpected identifier error as the loader expects a full file name including .js. The other form of this error occurs through the use of a protocol, which will load the resource as if it is not an AMD file.

  • Error Topic – SyntaxError:
    missing ) in parenthetical

    Prototype –

    SyntaxError: missing ) in parenthetical http://localhost/mydomain/js/dojosrc/dojo/_base/json.js
    Line 26

    I encountered this error, my environment is

    ·
    server – architecture (linux i686,ubuntu12.04,apache2,php
    5.3.8)

    ·
    user agent – {all browsers(google,chrome,and
    mozilla)}

    ·
    dojo version (1.8) and component emitting error “dgrid/OnDemandGrid” and “dojo/store/JsonRest”

    ·
    other environmental vars (using PHP Codeigniter
    framework)

    ISSUE STATUS #RESOLVED

    [Proposed cause]

    The problem seems to have been caused by passing an illegal character to the server via the URI when requesting for grid data more data using the JSON REST Store.

    Some PHP implementation environments do not allow for some characters in the uri i.e parenthesis like
    the case if you ask dgrid to sort results.(on startup the error
    rarely occurs ) . The URI schema your

    URI error generated by “sort( username)” possibly parenthesis
    in the URI

    [remedy]

    1. allow for parenthesis in your URI
    parsing Scheme

    2. always use the “sortParam”
    in your JsonRest constructor.

    3. employ a URI
    rewriting strategy such as mod_rewrite
    for those using apache

    4. give up – hahahahaha
    (seriously 1 to 3 you should at least try one of them)

  • As a note of another issue recently encountered:

    If you’re getting weird issues with `mid is null` that are only happening in IE8 and lower, check your dependencies array. For example, this is a real thing I just had:

    define([

    “dojo/_base/lang”,
    “dojo/_base/declare”,
    ], function(lang, declare) { /*…*/ });

    The problem is that trailing comma in the deps array. IE would iterate over the full array and try to dereference the mid of the third item in the array (which does exist, and is undefined), and thus it would error.

  • Trailing or missing commas in a dojoConfig, or within arrays in a dojoConfig such as packages can lead to some interesting errors as well.

  • Armand Mey

    Im trying to add dom/fx in the define tag, but after doing that i get this exception.

    Error on domReady callback: ReferenceError: fx is not defined

    define([
    “dojo/dom”,
    “dojo/fx”,
    “dojo/domReady!”
    ]…..

    Can someone tell me what could be the problem?
    also fx.js is in the same folder as dojo.js

  • Here’s a new one… Uncaught TypeError: Cannot read property ‘style’ of null… happens if you try to reference a node by id without a node of that id available. See http://jsfiddle.net/dylan/rD24x/1/ for an example

  • Satish Madiwal

    Hi, I am using Dojo 1.9. I have defined one border container and then 2 content panes. Out of which one has “splitter” as “true”. Now with this scenario, when I drag the splitter once, it works. But after that it gets disabled. I mean to say I can not drag it. Please help me.

  • I discovered a new one possibly. Here’s the error in FF (and a very similar warning in Chrome):

    dojo/parser::parse() error Error: Unable to resolve constructor for: ‘parseOnLoad: 0, isDebug: 1’

    …([isString(pair[0]) ? new RegExp(“^” + escapeString(pair[0]) + “$”) : pair[0], p…
    This occurred when I specified data-dojo-config accidentally as data-dojo-type on my script tag for including dojo.js

  • earnadvice.com

    i have trid all of other ways but few works fine like this
    http://www.earnadvice.com/what-is-a-sim-card/