May 11 2007

AJAX - Calling Webservices and Callback Functions

Category: AJAX-ATLASBil@l @ 08:11

I was playing around with creating an AJAX client class, in which I had a function to call a Webservice. I specified the callback function to run when the response is back from the Webservice.

The code is as follows:

        // Define a namespace
        Type.registerNamespace("Testing");
       
        // MaintainState constructor
        Testing.MaintainState = function(element) {
            this._element = element;
            this._text = "";
        }
       
        // Methods & Properties
        Testing.MaintainState.prototype = {
       
            get_Element:function() { return this._element; },
            set_Element:function(value) { this._element = value; },
           
            get_Text:function() { return this._text; },
            set_Text:function(value) { this._text = value; },
                       
            BeginServiceCall:function() {
                this.set_Text("Bilal");
                WebService.RunDummyMethod(this.EndServiceCall, this.OnError, this.OnTimeOut);
            },
           
            EndServiceCall:function(result) {
                var pnl=$get(this.get_Element());
                if (pnl.innerText != null) {
                    pnl.innerText = this.get_Text();
                }
                else{
                    pnl.textContent = this.get_Text();
                }
            },
                      
           OnError:function(result) {
                alert(result.get_message());
           },        
          
           OnTimeOut:function(result) {
                alert(result);
           }
        }

        Testing.MaintainState.registerClass("Testing.MaintainState");
       
        // Notify ScriptManager that this is the end of the script.
        if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

When you run the BeginServiceCall, a call to the Webservice dummy method is done and a callback method is specified which is EndServiceCall. If you notice that inside the EndServiceCall, I referenced properties on the client class "MaintainState" by using this. This would through an exception since the callback methods are not executed in the same context of the calling clas.

The problem is in here:

            EndServiceCall:function(result) {
                var pnl=$get(this.get_Element());
                if (pnl.innerText != null) {
                    pnl.innerText = this.get_Text();
                }
                else{
                    pnl.textContent = this.get_Text();
                }
            },

I am referencing the this.get_Text() property in the callback method, this in this case is null! So I will not be able to see the text that I placed in the BeginServiceCall function above!

To be able to maintain the state of the class in the callback functions, read here:

Thanks to Bipin Joshi(www.dotnetbips.com) with whom I discussed this issue (same problem happened in Bipin's lastest article) and Rob Bagby(www.robbagby.com) who gave me the right explanation why this code doesn't work as we might think it works in C# or any OO language! The solution is to use this instead:

WebService.RunDummyMethod(Function.createDelegate(this, this.EndServiceCall), Function.createDelegate(this,this.OnError), Function.createDelegate(this, this.OnTimeOut));

What happens now is that, we told the AJAX environment to run the callback method in the context of "this" class or the current class!

Now the code works fine!

Hope this helps!
Regards

Tags:

Comments are closed