views:

2975

answers:

1

The following code in javascript gives me the error "this.callback is not a function

function ajaxRequest()
{
    var httpObject;

    this.open = open;
    this.callback = function(){};

    function getHTTPObject()
    {
     if (window.ActiveXObject) 
      return new ActiveXObject("Microsoft.XMLHTTP");
     else if (window.XMLHttpRequest)
      return new XMLHttpRequest();
     else 
     {
      alert("Your browser does not support AJAX.");
      return null;
     }
    }

    function onstatechange()
    {
     if(httpObject.readyState == 4)
     {
      this.callback(httpObject.responseText);
     }

    }


    function open(url, callback)
    {
     httpObject = getHTTPObject();
     if (httpObject != null) 
     {
      httpObject.open("GET", url, true);
      httpObject.send(null);
      this.callback = callback;
      httpObject.onreadystatechange = onstatechange;
     }
    }
}

why doesn't open method treat the callback parameter as function?

If it does then why can't i call it in onstatechange function?

How do i make this work?

+6  A: 

The reason is that because onstatechange is being called as an event handler, and the this pointer is likely pointing to the object on which the event fired, not the ajaxRequest object, as you expect.

The below rewrite stores the this variable in a variable called that in the execution context to which the onstatechange() function has access. This ought to cure the problem.

The long and short of all this is if you don't thoroughly understand Javascript closure and execution contexts, and even if you do, you're much, much better off using a framework to do your AJAX requests. jQuery and Prototype are good choices.

function ajaxRequest()
{
    var httpObject;

    this.open = open;
    this.callback = function(){};
    var that = this;

    function getHTTPObject()
    {
        if (window.ActiveXObject) 
                return new ActiveXObject("Microsoft.XMLHTTP");
        else if (window.XMLHttpRequest)
                return new XMLHttpRequest();
        else 
        {
                alert("Your browser does not support AJAX.");
                return null;
        }
    }

    function onstatechange()
    {
        if(httpObject.readyState == 4)
        {
                that.callback(httpObject.responseText);
        }

    }


    function open(url, callback)
    {
        httpObject = getHTTPObject();
        if (httpObject != null) 
        {
                httpObject.open("GET", url, true);
                httpObject.send(null);
                this.callback = callback;
                httpObject.onreadystatechange = onstatechange;
        }
    }
}
Triptych