Vishful thinking…

Writing better javascript – Part 10

Posted in javascript by viswaug on November 29, 2008

Parasitic Inheritance

I had written about using the JavaScript module pattern to better organize and structure your code. If you like using the module pattern and are liking it enough to be writing complex code libraries with it, then you might want to explore and utilize OO inheritance in your classes. This can be achieved by using the parasitic inheritance pattern.

Let’s say that you have written a base class called ‘MapToolbarItem’ using the module pattern like below.

Base Class

var MapToolbarItem = function(toolbarItemID, options) {
    //Declare private variables here
    var _element;

//Declare private methods here
    var _enable = function() {
        //implement function here
    };

var _disable = function() {
        //implement function here
    };

return {
        //Declare public variables here
        element: _element,

//Declare public methods here
        enable: function() {
            _enable();
        },

disable: function() {
            _disable();
        }
    };
};

The class below illustrates how to create a ‘MapTool’ class that inherits from the ‘MapToolbarItem’ class using the parasitic inheritance pattern.

Inherited Class

var MapTool = function(toolID, options) {

//Declare a variable (called ‘that’ here) and assign an instance of the base class to it
    var that = new MapToolbarItem(toolID, options);

//Declare private variables here
    var _state;

//Declare private methods here
    var _select = function() {
        //Implement function here
        //Public variables of the base class can be used here
        that.enable();
    };

var _unselect = function() {
        //Implement function here
        //Public variables of the base class can be used here
        var el = that.element;
    };

//Declare public variables here
    //The public variables are created on the ‘that’ variable holding the base class instance
    that.state = _state;

//Declare public variables here
    //The public methods are created on the ‘that’ variable holding the base class instance
    that.select = function() {
    };

that.unselect = function() {
    };

//return the ‘that’ object
    return that;
};

The pattern is pretty simple enough where new public variables and methods are attached to an instance of the base class and then the instance of the base class is returned

Advertisement

HTTP header status

Posted in Uncategorized by viswaug on November 26, 2008

We have been building a completely RESTful interface for editing data served up by the ArcGIS Server MapServices. It is a supplement to the ESRI REST services which does not expose all the functionality that we need through its REST API. It has turned out great so far and has been amazingly easy to work with when building applications using the JS API. One of the important things to keep in mind when building RESTful interfaces to your data is to abide the REST principles. So, being true to the REST principles, we need to respond to the HTTP requests that produce an error on the server when processing it with the corresponding HTTP status headers. It is tricky to walk through all those conditions in your head and decide on the correct HTTP status that needs to be returned. Well, this flowchart below from Alan Dean should help with process and make it easier to figure out what status code to return.

http-headers-status

 

We also have built a JavaScript “Table of Contents (TOC)” control built for the ESRI JS API which uses a custom RESTful service on the back-end to return all the data needed to build the Table of Contents. We also use the ArcGIS Server SOAP API in our TOC REST service to get the data and the swatches for the Table of Content. Which should allow us to deploy the TOC REST service on any web server without needing a server license. I hope to be posting a link to a working demo of the Table of Contents component pretty soon. In the meanwhile, if you are building a Table of Contents component yourself, one bit of advise that you might consider is to leverage the ASP.NET cache to store the response for the TOC data. Depending on the complexity of your MapService, the response from ArcGIS Server when requesting map legend data could range from long to extra-ordinarily long. In the case of our MapService, when requesting the map legend data from ArcGIS Server, the response took 7 seconds on an average. But the response from our TOC REST service almost take no time at all once it has been cached in the ASP.NET cache.

Windsor Container – Satisfying dependencies

Posted in Uncategorized by viswaug on November 24, 2008

I have been using the Windsor container Dependency Injection (DI) framework for my Inversion of Control (IoC) needs lately and have been highly pleased with the flexibility it offers to satisfy the different dependencies for components. Some of the ways by which Windsor container allows for the dependencies to be satisfies are:

1) Setting constructor parameters
2) Setting properties on components
3) Setting up dependencies on other components that have been configured – the ${…} syntax
4) Setting up common properties that can be used to instantiate different components – the #{…} syntax
5) Passing in the dependencies as a dictionary
6) Using the Factory Facility to obtain the dependency from a custom factory class

That should cover all the scenarios that you would ever come across right? Wrong. I had a weird requirement wherein I wanted to pass in one of the dependencies (as a dictionary) and configure two more dependencies in the configuration file.

Here is the definition of the class that I had to create

public LOBLayer(IFeatureClass featureClass, string layerName, string keyFieldName)

I wanted to configure the ‘layerName’ and the ‘keyFieldName’ constructor parameters in the configuration file and pass in the ‘featureClass’ object in the dictionary parameter of the Resolve(…) method. So, I needed to be able to do the following

<component id=”LOB” lifestyle=”transient” service=”GIS.IGISLayer, GIS” type=”BizLogic.LobLayer, BizLogic”>
  <parameters>
    <layerName>LOB</layerName>
    <keyFieldName>OBJECTID</keyFieldName>
  </parameters>
</component>

and

System.Collections.IDictionary parameters = new System.Collections.Hashtable();
parameters.Add(“featureClass”, featureLayer.FeatureClass);
IGISLayer destinationLayer = _container.Resolve<IGISLayer>( featureType, parameters );

 

Initially, I was skeptical as to whether Windsor would be smart enough to handle it. But, the Windsor container came through for me. I was able to configure two of the constructor parameters in the configuration file and pass in the third dependency in a dictionary to the Resolve(…) method.

Writing better javascript – Part 9

Posted in Uncategorized by viswaug on November 23, 2008

Use Event Delegation and be mindful of the number of event handlers that you are adding

Every time you are adding event handlers to the DOM elements of your web page you are adding to the memory usage of the DOM. So, adding a lot of event handlers in the web page can increase your memory usage. Also, there are greater chances of memory leaks happening if you are not careful writing your code. This may not be a big factor in most cases but it is always good to be aware of what is happening in your code. Especially because most of the JavaScript frameworks can make it real easy to write code which may not be optimal in some cases. This is especially a factor when dealing with tables and list etc. Where the number of elements you are attaching an event handler could potentially be a large number.

Consider the case where you want to the users to be able to delete a row in a table by clicking on the first cell in the row. When thinking about implementing this requirement, it is easy to write something like this when using the jQuery framework

$(“table#large tr td:first-child”).click(function(e) {
    $(this).parent(“tr”).remove();
});

In the case above, you are attaching an event handler to a cell in every row of the table. If your table contains are large number of rows, you will be attaching potentially thousands of event handlers to your DOM. This may not be an optimal solutions. These kinds of circumstances can be tackled in another better way using the event bubbling property of the DOM. We can attach attach just a single event handler to the table itself instead of every first cell of every row in the table and use the ‘originalTarget’ property of the jQuery event object to determine whether the user clicked on the first cell in a row and then proceed to remove the row as needed. This technique of attaching the event handler to the container and to the individual elements is sometimes referred to as ‘Event Delegation’. The above code snippet can be re-written to read like below using Event Delegation.

$(“table#large”).click(function(e) {
    if (e.originalTarget.tagName == “TD”) {
        if (e.originalTarget === $(e.originalTarget).parent(“tr”).find(“:first-child”).get(0)) {
            $(e.originalTarget).parent(“tr”).remove();
        }
    }
});

You shouldn’t have to worry about this scenario too much unless if the number of items you are dealing with is considerably large. But it is good to be aware of it and this knowledge might come in handy when you are trying to trace performance issues or memory leak origins.

Another HUGE benefit of using the Event Delegation technique is that when new rows are added to the table via AJAX then we don’t have to worry about attaching the event handlers to the newly added rows. Everything will just keep working as expected as we have just attached the event handler to the containing DOM element which then checks for the expected conditions.

Writing better javascript – Part 8

Posted in javascript by viswaug on November 21, 2008

JavaScript event model

This is another practice I have adopted in my JavaScript development to enable the components I create be able to raise custom events and have an event model that will support consumers to be able to use them as needed. That said, please do let me know if this event model can be improved upon in anyway possible. Always open to comments and suggestions…

In the code illustration below, I am adding the ‘click’, ‘select’, ‘unselect’, ‘enable’ and ‘disable’ event support to my MapTool JavaScript component. If you have been building mapping application then it should be evident why I would need those events on my map tools. I create a private listeners object where I store the listeners for every supported event as properties with the same name as that of the event. That makes it a little easier to retrieve the array of listeners for a certain named event. I also throw an error if the user tries to add a listener to an event that has not been pre-defined. This is obviously optional and be handled a couple of different ways. If the user tries to add a listener to an event that has not been pre-defined, the add listener call can just be ignored or a new event with that name can be added to the listeners object (but I don’t have such requirements in my applications so I throw an error). I also use the code snippet from John Resig (jQuery’s father) to be able to remove items from an array. That function can also be added to the array prototype if you are comfortable with messing the Array prototype.

var MapTool = function(toolID, options) {
    //private properties
    var _listeners = new Object(); //Create an object that hold the arrays of listeners as its properties
    //Predefine known events on the object – optional
    _listeners.click = new Array();
    _listeners.select = new Array();
    _listeners.unselect = new Array();
    _listeners.enable = new Array();
    _listeners.disable = new Array();

    //Adding John Resig’s array remove function
    _removeFromArray = function(array, from, to) {
        var rest = array.slice((to || from) + 1 || array.length);
        array.length = from < 0 ? array.length + from : from;
        return array.push.apply(array, rest);
    };
    //

    var _raiseEvent = function(eventName, e) {
        if (_listeners[eventName]) {
            for (var i = 0; i < _listeners[eventName].length; i++) {
                if (_listeners[eventName][i]) {
                    _listeners[eventName][i](e);
                }
            }
        }
    };

    var _clearListeners = function(eventName) {
        if (_listeners[eventName]) {
            _listeners[eventName] = new Array();
        }
    };

    return {
        createListener: function(eventName) {
            if (!_listeners[eventName]) {
                _listeners[eventName] = new Array();
            }
        },

        addListener: function(eventName, listener) {
            if(typeof(eventName) !== ‘string’ || typeof(listener) !== ‘function’) {
                if (!_listeners[eventName]) {
                    throw “The event ‘” + eventName + “‘ is not supported by MapTool.”;
                    //_listeners[eventName] = new Array(); – this is another option if you don’t want to throw an error if the user tries to add a listener for an unknown event
                }
                return { name: eventName, index: _listeners[eventName].push(listener) };
            }
            else {
                throw “Cannot add event listener. Invalid argument. A valid event name and listener function is required.”;
            }
        },

        removeListener: function(eventObj) {
            if (eventObj && eventObj.name && (eventObj.index || eventObj.index === 0)) {
                if (_listeners[eventObj.name]) {
                    _removeFromArray(_listeners[eventObj.index], index);
                }
            }
            else {
                throw “Cannot remove listener. Inavalid event listener object.”;
            }
        }
    };
};

 

The above event model has been working pretty good for me and the requirements in my applications.

Writing better javascript – Part 7

Posted in javascript by viswaug on November 21, 2008

The options argument

This practice is something that came to me after I ran into some flexibility issues with the JavaScript components I was creating. If you have been following this series, you might have noticed that I use the module pattern to create my JavaScript classes. As our JavaScript library started growing in size and the components I was creating was getting more complex, there was a need to be able to allow for ways to configure them wherever possible. Coming from the .NET universe, I started doing what I would have done if I was writing C# classes. I started modifying the constructor for the classes and started adding the different configurations points as arguments to the constructor like below.

var FormHelper = function(formID, cssClass, validationRules, submitHandler, cancelHandler/*constructor arguments defined here*/) {

    //Declare private variables here

    //Declare private methods here

    return {

    //Declare public properties here

    //Declare public methods here

};
};

The class just started off with ‘formID’ as the only argument. But as I started adding more extensibility points, I had started adding more arguments seen above like ‘cssClass’, ‘validationRules’, ‘submitHandler’ and ‘cancelHandler’ etc. These arguments started getting out of hand as I needed more extensibility points. And since JavaScript is JavaScript, I had to pass in the correct arguments in the exact index at which the argument is expected. Not a real good way of doing things. Thinking about it a little more and dwelling on it for a while I realized that the solutions was just to take an options argument that contains all the extensibility points as properties on it. See the changes below

var FormHelper = function(formID, options/*constructor arguments defined here*/) {

    //Declare private variables here

    //Declare private methods here

    return {

    //Declare public properties here

    //Declare public methods here

    };
};

var formOptions = {
    cssClass: “someClass”,
    validationRules: rules,
    submitHandler: handleSubmit,
    cancelHandler: handleCancel
};

var test = new FormHelper(“LatLongForm”, formOptions);

Doing it that was much cleaner. And didn’t have to change the definition of the constructor every time I wanted to add more extensibility points. Once I started writing my classes that way, I started noticing that the above pattern was used all the major JavaScript libraries. Probably should have seen the reason behind it earlier when I was using those libraries. But, now I know and am probably a better developer for it. But you don’t have to make that mistake and learn from my experience and follow this pattern from the get go.

Writing better javascript – Part 6

Posted in javascript by viswaug on November 19, 2008

 

One of the most commonly used debugging techniques when writing JavaScript is to use the ‘console.log(…)’ function available when using Firebug to print out useful information to help understand context and program flow. But the Firebug console object comes packed with a whole suite of other functions that can make your life even easier. The ones that I use most often are the ‘console.dir(object)’, ‘console.time(name) & console.timeEnd(name)’ and the ‘console.profile([title]) & console.profileEnd()’ functions.

console.dir(object) – Prints an interactive listing of all properties of the object. So, now you won’t have to find the code block and specify a breakpoint everytime you debug.

console.time(name) & console.timeEnd(name) – This pair of function starts and stops a named timer. So, this is invaluable in scenarios where you would like to have time estimates on processing heavy operations. I made heavy use of it when I was utilizing JavaScript templating in my applications. I was able to obtain the time taken for the processing the template and also for applying the template to an Object. I hope to be posting about the JavaScript templating techniques and their performance pretty soon in this series.

console.time(“Process template”);

var template = processTemplate(templ);

console.timeEnd(“Process template”);

console.time(“Apply template”);

var result = applyTemplate(template, data);

console.timeEnd(“Apply template”);

console.profile([title]) & console.profileEnd() – The profile view of the console tab in Firebug can sometimes be too overwhelming. In those cases, using this function pair will help narrow down your scope of search.

There are a bunch of other functions on the console object too and you should check it out. You never know when some of those functions could save your computer from having to listen to all those obscenties that you yell at it.

Writing better javascript – Part 5

Posted in javascript by viswaug on November 19, 2008

Use the module pattern to better organize your code.

Good JavaScript programming practices will help you debug and diagnose problems better. It will also keep you sane when the applications grow bigger and will be more maintainable. One of the things that I tend to do these days when I see any applications developed using the ESRI JS API, Google Maps API or the VirtualEarth API is to do a “View Page Source” on the we page. It is surprising to see many of those applications have a considerable amount of application logic on the web page itself as a series of javascript functions. I have been using the JavaScript module pattern to better organize my code and I find it satisfactory for most of my requirements. Obviously, that is not the only way to organize your code but I like it because it helps me think in terms of classes with private & public properties and methods.

Creating a class using the module pattern is pretty simple. The snippet below illustrates how to create a new class. It is only an illustration of the technique and doesn’t mean much.

var MapManager = function(/*constructor arguments defined here*/) {

    //Declare private variables here
    var _mapElement;

    //Declare private methods here
    var _addLayer = function(layer) {
        //private properties and methods CAN be accessed here
        //public properties and methods CANNOT be accessed here

        //add the layer here
    };

    return {

        //Declare public properties here
        element: _mapElement,
        data: new Object(),

        //Declare public methods here
        addLayer: function(layer) {
            //private properties and methods CAN be accessed here
            _addLayer(layer);
        }
    };
};

The class ‘MapManager’ defined above defines its private and public memebers. When an instance of the ‘MapManager’ class is created the instance returned can only be used to access and change its public properties and methods and not its private members.  The ‘new’ keyword can be used to create an instance of the ‘MapManger’ class like below.

var instance = new MapManager();

Just for a little insight into the technique, when you create an instance of the class, the object that is defined as a JSON literal after the ‘return’ keyword is the object that gets returned. And this returned object still has access to the private members in the class definition above because of the concept of closures in JavaScript.

This technique should be satisfactory for most simple design needs but most JavaScript frameworks offer their own technique to create classes, inherit from them and other advanced OO concepts. I hope to post at a later time on inheritance when using the module pattern.

Writing better javascript – Part 4

Posted in javascript by viswaug on November 19, 2008
JavaScript arrays are not associative.

I am not going to be writing about a JavaScript technique here but just about a JavaScript syntax which sometimes is not well understood. Arrays in JavaScript can be used a couple of ways like below.

var test = new Array();
test[0] = “Here is something”;
test[“name”] = “Here is another thing”;

As you can see, the array instance above is indexed using an integer and then a string. But an array by definition should only be indexed by an integer and not a string. So, how does JavaScript allow this? Well, JavaScript really doesn’t. Then how does the above piece of code work? Well, when you write something like “test[‘name’] = ‘Here is another thing'” what is really happening is that the value specified is not added to the list of items in the array but it gets stored in a property called ‘name’ on the array. The only reason the above syntax works is because an Array in JavaScript is also an Object. So, the value can also be retrieved by referencing ‘test.name’.

One last thing that I want to add to this post is how to iterate over all the properties of an Object.

var test = new Object();
test[“firstname”] = “Bill”;
test.lastname = “Gates”;
for(var item in test) {   
alert(test[item]);
}
//this should alert ‘Bill’ and ‘Gates’

This may not be news to everybody but it took me a while to realize this when i started writing JavaScript.

Writing better javascript – Part 3

Posted in javascript by viswaug on November 18, 2008

Writing AJAX applications involves a lot of scenarios where the data sent from the server to the browser needs to be inserted into the web page as appropriate HTML elements. When using JavaScript to dynamically inject contents into your HTML page, it is better to use the ‘innerHTML’ property of the DOM element and injecting all the contents as a string into the HTML page. This method even though seemingly ugly is faster than using DOM manipulation methods on the document object like ‘document.createElement(…)’ and ‘element.appendChild(…)’ etc to insert dynamic contents.

Check out the benchmarks on the performance benefits of using the ‘innerHTML’ property over the DOM manipulation methods here at QuirksMode. If you are a bigger stickler for performance and the gains from using ‘innerHTML’ doesn’t satisfy you, then you might consider using the ‘replaceHTML’ function below as per the suggestions posted here.

function replaceHtml(el, html) {
	var oldEl = typeof el === "string" ? document.getElementById(el) : el;
	/*@cc_on // Pure innerHTML is slightly faster in IE
		oldEl.innerHTML = html;
		return oldEl;
	@*/
	var newEl = oldEl.cloneNode(false);
	newEl.innerHTML = html;
	oldEl.parentNode.replaceChild(newEl, oldEl);
	/* Since we just removed the old element from the DOM, return a reference
	to the new element, which can be used to restore variable references. */
	return newEl;
};