Pass arguments into ajax onreadystatechange callback?

What's the normal pure javascript (i.e. not JQuery) way to pass arguments into an anonymous onreadystatechange callback?

For example:

function doRequest(){
    /* Get an XMLHttpRequest in a platform independent way */    
    var xhttp = getXmlHttpRequestObject(); 

    var msg="show this message when done"; /* another variable to pass into callback */

     /* How do I pass 'msg' and 'xhttp' into this anonymous function as locals
       named 'x' and 'm'??? */
    xhttp.onreadychangestate=function(x,m)
    {
       if( x.readyState == 4 )
       {
           alert(m);
       }
    }
    /* do the open() and send() calls here.... */
}

Answers:

Answer

Javascript supports closures, so the anonymous function you wrote will be able to access xhttp and msg from the enclosing doRequest() scope.

If wanted to do this explicitly (say, if you want to define the callback function somewhere else in the code and reuse it), you could create a function that creates the callbacks. This also allows you to alias the variables to be accessible with different names (like x and m):

function createCallback(x, m) {
    return function() {
        /* Do whatever */
    };
}

and then in doRequest(), do xhttp.onreadystatechange = createCallback(xhttp, msg);

If all you wanted to do was 'rename' the variables, you can do this inline and anonymously:

xhttp.onreadystatechange = (function(x, m) {
    return function() {
        /* Do stuff */
    }
})(xhttp, msg);
Answer

Part of the above answer didn't work for me. First, for a separate callBack function having no parameters:

 xhttp.onreadystatechange = callBack;   //works; the function's NAME is required

Now suppose the callBack function is modified to receive some parameters:

 xhttp.onreadystatechange = callBack(x,m); //didn't work, and didn't know why
 xhttp.onreadystatechange = createCallback(xhttp,msg); //bad part of above Answer

However, elsewhere here at StackOverflow someone explained that it had to do with the need to assign a "function reference" instead of a "function call" to onreadystatechange (like the NAME above is a function reference), and posted a solution:

 xhttp.onreadystatechange = function(){callBack(x,m);}; //works

I came here to add something to that other Answer, but now can't find it. So I might as well add it here. In my own code I was using both local variables and global variables, and discovered something that didn't seem to work right, but now that I know what actually happened, a Word Of Warning seems appropriate. Assume "g" is a global variable:

 xhttp.onreadystatechange = function(){callBack(x,g);};//anonymous function works

The function reference is assigned to onreadystatechange at some point in time (T0), and the callBack function is called called at a different time (T1). Well, the value of global variable "g" at T1 is the value that gets passed to the callBack function, NOT the value of "g" when the function reference was assigned at T0. Don't let this bite you like it bit me! (Local variables generally don't have this problem because they are usually out of scope at T1, so JavaScript has to use their existing values at T0, when setting the parameter-values of the anonymous function.)

Answer

Never too late! :-)

Instead of passing data using arguments in xhttp.onreadystatechange which is somewhat complicated, one can just add properties to the xhr object itself.

For instance:

var m = "Hello!";
var xhttp = new XMLHttpRequest();
xhttp.m = m;
xhttp.onreadystatechange = function()
{
    var x, m;
    x = this;
    m = x.m;
    if ((x.readyState == 4) && (x.status == 200))
    {
        alert(m);
    }
};
// ...

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.