Atlas 6: When 'this' is not really 'this'

Atlas callbacks are not executed on the same context where they are called. For ex, if you are making a Page method call from a javascript class like this:

function SampleClass() { this .id = 1 ; this .call = function () { PageMethods.DoSomething( " Hi " , function (result) { debug.dump( this .id ); } ); } }

What happens when you call the "call" method? Do you get "1" on the debug console? No, you get "null" on the debug console because "this" is no longer the instance of the class. This is a common mistake everyone makes. As this is not yet documented in Atlas documentations, I have seen many developers spend time finding out what's wrong.

Here's the reason. We know whenever Javascript events are raised "this" refers to the html element which produced the event. So, if you do this:

 

function SampleClass() { this .id = 1 ; this .call = function () { PageMethods.DoSomething( " Hi " , function (result) { debug.dump( this .id ); } ); } }

<input type="button" id="ButtonID" onclick="o.onclick" />

If you click the button, you see "ButtonID" instead of "1". The reason is that, the button is making the call. So, the call is made within button object's context and thus "this" maps to the button object.

Similarly, when Xml Http raises the event onreadystatechanged which Atlas traps and fires the callback, the code execution is still on the Xml Http's context. It's Xml Http object which raises the event. As a result, "this" refer to the Xml Http object, not to your own class where the callback is declared.

In order to make the callback fire on the context of the instance of the class so that "this" refers to the instance of the class, you need to make the following change:

function SampleClass() { this .id = 1 ; this .call = function () { PageMethods.DoSomething( " Hi " , Function.createDelegate( this , function (result) { debug.dump( this .id ); } ) ); } }

Here, the Function.createDelegate is used to create a delegate which calls the given function under the "this" context. Function.createDelegate is defined in AtlasRuntime:

Function.createDelegate = function (instance, method) { return function () { return method.apply(instance, arguments); } }
Published Sat, Sep 23 2006 17:46 by omar
Filed under: