I’ve been smashing my head against this all day - but I finally got something working consistently and reliable, so I better damn well document it. This is as good a place as any, and hopefully it will be useful to others.

I needed to make an Ajax call, so I turned to my good friend XMLHttpRequest. One wrinkle was that I needed to pass in a parameter to it… so I tried:

var test = "bar";
req = new XMLHttpRequest();
req.open("GET", myURL, true);
req.foo = test;
req.onreadystatechange = function() {
    if (this.readyState != 4)
        return;
    if (this.status == 200) {
        alert(this.foo);   // should print out "bar"
    }  
}
req.send(null);

For the most part this worked. Except every now and then… when it didn’t. Most annoyingly, it failed pretty consistently when I was trying to use it within a nested Ajax call (complicated code, don’t ask.. it’s not interesting).

I’m not sure why it doesn’t work to be honest. From my understanding, req.foo should just instantiate a new foo member variable of the XMLHttpRequest object I just created and set it to be referenced via ‘this.foo’ inside any member function. I’m guessing it’s something to do with the scoping of onreadystatechange being set to the reference of an anonymous function so the anonymous function isn’t actually part of the XMLHttpRequest object and thus doesn’t have access to its member variables. What’s frustrating is that it works most of the time. A consistent failure model would actually be more helpful here.

Anyway, enough blabbering, here’s what seemed to work for me:

var test = "bar";
req = new XMLHttpRequest();
req.open("GET", myURL, true);
req.onreadystatechange = function(foo) {
    return function() {
        if (this.readyState != 4)
            return;
        if (this.status == 200) {
            alert(foo);
        };
    }(test);
}
req.send(null);

Now that works reliably for me 100% of the time.

Tags: ,

8 Responses to “passing parameters to XMLHttpRequest’s onreadystatechange function”

  1. Jon H Says:

    I bet that in your first example, if you used:

    alert (this.parentNode.Foo)

    it would work.

    this.Foo inside the scope of the anonymous function is scoped wrong.

  2. Stephen Lau Says:

    Nope, trying to do that just got me errors that “this.parentNode” didn’t exist (or had no attributes)

  3. nico Says:

    Thanks, that really saved me from a long night of trying to figure out some hideous hack. :)

    Just out of curiosity: how on Earth did you came out with that????

  4. Stephen Lau Says:

    Glad it was helpful. :) I’m honestly not sure how I came up with it. Probably through some combination of beer, and helpful colleagues.

  5. Todd dellagio Says:

    Hey thanks for this post. I was having a very similar issue and that got resolved. Thanks lau.

  6. Scott F Says:

    Thanks a lot for your help. I was having the same scope problems.

  7. Will Says:

    Hi,

    I tried this method - no joy.

    Any ideas where I’m messing up? Thanks.

    I’m trying to pass the variable ‘url’ down to the next function.

    function getData(url) { var datatosend=”graphrequest=graphcounter1″; var req = new XMLHttpRequest(); req.open(”POST”, url, true); req.onreadystatechange = function(url) { return function() { document.getElementById(”zone1″).innerHTML = “0″; if(req.readyState == 4 && req.status == 200) { document.getElementById(”zone1″).innerHTML = req.responseText;
    setTimeout(”getData(url)”, 3000); //refresh rate for graph (ms) } }(url); };
    req.setRequestHeader(”Content-Type”, “application/x-www-form-urlencoded”); req.send(datatosend); }

  8. Krishna Says:

    var req = initRequest(url); req.onreadystatechange = function() { if (req.readyState != 4) return; if (req.status == 200 ) { //alert(flagforsubmit); flagforsubmit = true;

                loadXML(req.responseXML);                   
               }    
    
       };      
       req.open("GET", url, true);       req.send(null);
    

    if(flagforsubmit){ ///code is not executed } since the flagforsubmit is not true its is taking too much time for execute and when i click the button on which i have called the function is not working(no action) after pressing 3 /4 times the output will come,

Leave a Reply


Recent posts