Pass arguments into ajax onreadystatechange callback?
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.)
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);