July 2010 Entries
JavaScript Inheritance

I've spent the last few weeks trying to comprehend OOP and inheritance in JavaScript. After that amount of time I've come to the conclusion that harly anyone really understands it and everyone implements it a different way. Just look at this question someone posted about the best library to use for JS inheritance. I thought it was funny because although there were a lot of answers, I think everyone proved his point, that there are many of them and no one could agree on the best.

stackoverflow.com/questions/711209/which-javascript-library-has-the-most-comprehensive-class-inheritance-support

Being simple minded and wanting to find the simplest way to do some class inheritance I read a number of books and blogs. Every one I read made me more confused. It can't be that hard, I thought. But JS is a strange beast, and prototypal inheritance doesn't translate very well for someone used to classical class inheritance.

I think the main problem is there are too many different ways to define objects in JS. In other languages such as C# or Java there's pretty much one way to do it, and it's simple to understand. You create a class, then you create a child class that extends it and adds to or overrides the parent's behavior.

I could have just used the first way I found and forgot about it and kept programming. But not me. I kept thinking there has to be a better way to do it. There has to be an industry standard. Right? Not! So finally I just kind of combined the best parts of all the solutions I could find and came up with something that worked and looked good. Most of the ideas I got came from Gavin Kistner's site, which does a good job of explaining JS inheritance without creating a bunch of helper functions first.

phrogz.net/js/classes/OOPinJS2.html

The only difference from Gavin's example is that I define all of my child class functions inside of the object definition instead of using the prototype. I don't know if there is some reason not to do it that way but it worked for me.

Shape = {
   name: undefined,
   init: function(name) { this.name = name; }
   getName: function() { return name; }
}
function Circle(radius) {
    this.init("circle");
    this.radius = radius;

    this.getArea = function(){ return Math.PI * this.radius * this.radius; }
}
Circle.inheritsFrom(Shape);

var myCircle = new Circle(4);
myCircle.getArea(); // 50.265
myCircle.getName(); // circle

I define an init function in the base class so I don't have to worry about calling the base class's constructor. That solves problem #1. In my child class, Circle I call the init function and then do any other child initialization like setting the radius. Then I define all of my child class behaviors, in this case getArea(). Finally, outside of the child class definition I call the inheritsFrom function to link it to the parent. The inheritsFrom is defined at the page linked above. It simply sets the prototype to the parent object and sets the constructor.

Tha was the simplest thing I could come up with. I hope it saves someone else from days research.

ASP.NET Session Keep Alive

I was recently tasked with coming up with a way to keep the session alive in ASP.NET as long as the user had the web page open. That way if they started filling out a form, then went to lunch and came back, they wouldn't lose all of the information just because their session timed out.

The concept is actually pretty simple. You just need to make a call back to the server every once in a while before the session expires to update the session timeout. We figured as long as the user has the browser open on one of our pages they are still working on our site and want their session renewed. Once they leave our site the session can go ahead and expire normally. This would also allow us to reduce the session timeout so we could reclaim session resources on a more frequesnt basis for users that hit the site for a moment then leave.

The primary way I found to accomplish this by asking at the almighty Google was to have a blank image on the page and use javascript to update the image source so that the server is pinged and the session updated. But with ajax why bother? I figured I could do it a lot easier with a simple ajax call that didn't require any image on the page.

What I did was to create an empty aspx that didn't have anything in it, just the default html that Visual Studio generates. Then I created a javascript file that simply uses jquery to do an ajax get request to the empty page. The code is below.

SessionKeepAlive =
{
    delay: 10000,
    url: undefined,
    run: function()
    {
        if (this.url)
        {
            $.get(this.url + "?d=" + escape(new Date().getTime()));
            setTimeout("SessionKeepAlive.run()", this.delay);
        }
    },
    start: function(delay, url)
    {
        // Set ajax timeout to 2 seconds
        $.ajaxSetup({ timeout: 2000 });
       
        // Convert delay to millis
        this.delay = parseInt(delay) * 60000;
        this.url = url;
        setTimeout("SessionKeepAlive.run()", this.delay);
    }
};

You start the keep alive process by calling SessionKeepAlive.start() passing the number of minutes to wait and the url of the page to call. It uses setTimeout() to wait the specified amount of time before calling run(). In run() it does the get request and calls setTimeout() again so it keeps repeating until the user leaves the page. Note that I had to add a parameter to the url to get it to work right in IE. Without adding a unique parameter value to the url, IE was just using the cached results instead of going back to the server. I used the Date.getTime() function to get a unique parameter value.

Since all of my pages extend the same base class I was able to programatically add a link to the javascript file and also register a startup script to call the start() function in page_init.

ClientScript.RegisterClientScriptInclude("keepSessionAlive", "keepSessionAlive.js");
ClientScript.RegisterStartupScript(GetType(), "SessionKeepAlive", "SessionKeepAlive.start(10, 'ping.aspx');", true);

You could also do this in a master page, but I have a number of different master pages and only one page base class, so it was easier to put it in the base class.