|
|||||||
| JavaScript JavaScript (not Java) Discussion and technical support, including AJAX and frameworks (JQuery, MooTools, Prototype...) |
![]() |
|
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Hi all,
What I am trying to do is write a function that submits an XMLHttpRequest and in the callback, call a function back on my caller and pass in all arguments that the submit function received. Perhaps it's easier to demonstrate: Code:
function submitXMLHttpRequest(url, callbackFun /*, maybe other args here */)
{
var originalArgs = arguments; // grab args so callback can pass them thru
<snip>
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4)
{
if(req.status == 200)
callbackFun.call(req.responseText, originalArgs);
else
<snip>
Code:
function makeXMLHttpRequest()
{
submitXMLHttpRequest(url, callbackFun1, onearg);
}
function callbackFun1(response, args)
{
var onearg= arguments[3]; // get back the arg sent in the make call
}
Code:
function makeXMLHttpRequestAgain()
{
submitXMLHttpRequest(url, callbackFun2, somearg, anotherarg);
}
function callbackFun2(response, arguments)
{
var somearg= arguments[3];
var anotherarg = arguments[4]; // get back both args sent in the make call
}
Can someone help me understand why this doesn't work? I thought since the onreadystatechange is a closure, I have access to all of its enclosing scope, so shouldn't I have access to the original arguments passed into the submitXMLHttpRequest method so I can pass them through to the callback I desire? In some cases I have 3 parameters I need passed between methods, sometimes only 2, so instead of naming them, I wanted to pass via arguments. Thanks very much. |
|
#2
|
||||
|
||||
|
Try using a wrapper.
Code:
req.onreadystatechange = (function(topArgs){// anything else you may need
return function (aEvt) {
if (req.readyState == 4){
if(req.status == 200)
topArgs[3].call(req.responseText, topArgs);
else
////..............
})(arguments);// close the wrapper
__________________
If you are using PHP please use the [php] and [/php] forum tags for highlighting... The same applies to HTML and the forums [html][/html] tags. |
|
#3
|
|||
|
|||
|
Interesting! I've only been doing Javascript a couple of months, I've not even seen that technique and will give it a try.
|
|
#4
|
|||
|
|||
|
So I see where you are going with this scragar and I agree it should work but it doesn't. I've tried for hours without success. The desired callback function gets called but any arguments I have passed to it seem to be null. I can log the response in my readystatechange callback to ensure that I have one, then pass it to my callback that I trigger in the call statement and when I get there it's null.
Thanks for your help though, and for introducing me on to this technique. |
|
#5
|
||||
|
||||
|
Can you show me the code you are using? The code I posted should work, but since you had to edit it I understand how it's only too easy to remove something simple.
Also, if you get any error messages it might be worth posting those.
__________________
If you are using PHP please use the [php] and [/php] forum tags for highlighting... The same applies to HTML and the forums [html][/html] tags. |
|
#6
|
|||
|
|||
|
He he, dedicated guy, workin' on a Saturday!
Ok here it is and I've noticed something strange which I will point out after the code: calling script Code:
function doSomethingInteresting()
{
var url = "www....";
var threadId = "1234567";
submitXMLHttpRequest(url, testFunction, threadId);
}
function testFunction(response, passThroughArguments)
{
log (response);
}
Code:
function submitXMLHttpRequest(url, callbackFun)
{
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.onreadystatechange = (function (passThruArgs) {
return function (aEvt) {
if (req.readyState == 4)
{
if(req.status == 200)
{
log (req.responseText);
passThruArgs[1].call(req.responseText, passThruArgs);
}
else
log ('request for message ' + url + ' failed);
}
}; // end callback function
})(arguments); // end wrapper function and execute it immediately to preserve scope
req.send(null);
}
I have tried not passing the passThruArgs from onreadystatechange at all, so like this Code:
passThruArgs[1].call(req.responseText); I also tried passing the request in to the scope preserving function, so this: Code:
}; // end callback function
})(req, arguments);
|
|
#7
|
|||
|
|||
|
You need to use apply: callbackFun.apply(this, originalArgs).
|
|
#8
|
|||
|
|||
|
Hmmm, I thought because I was passing an array either call or apply would work...?
|
|
#9
|
|||
|
|||
|
No, use call for named parameters, use apply when sending an array object: https://developer.mozilla.org/En/Cor...Function/Apply
|
|
#10
|
|||
|
|||
|
Ah ok I read that, and interpreted it as if I wanted to pass a whole array I use apply, if I wanted to pass in individual args I could use call but that one of those args could be an array. Ok, I am clear on that now.
But I tried what you suggested, that's not working for me either. onreadystatechange function now says: Code:
log ('passthruargs length is ' + passThruArgs.length);
log (req.responseText);
passThruArgs[1].apply(this, passThruArgs);
Code:
function testFunction(response, args)
{
log ('response is ' + response.responseText);
log ('args length is ' + args.length);
log ('args 0 is ' + args[0]);
log ('args 1 is ' + args[1]);
log ('args 2 is ' + args[2]);
}
passthruargs length is 3 the responseText response is undefined args length is 2 args 0 is <url i passed in> args 1 is <entire definition of the testFunction function> args 2 is undefined So I'm not getting the response text and the third argument which are really the two things I need to be getting into my callback. |
|
#11
|
|||
|
|||
|
I see what's happening now:
var originalArgs = arguments; // grab args so callback can pass them thru <snip> req.onreadystatechange = function (aEvt) { if (req.readyState == 4) { if(req.status == 200) callbackFun.apply(this, originalArgs.splice(0,2, req.responseText)); That will remove the first two elements of originalArgs and add responseText to the start of the array. That should do the trick. |
|
#12
|
|||
|
|||
|
So the reponse text is the first argument, then all additional arguments start at index 1.
|
|
#13
|
|||
|
|||
|
Hm, ok, so you have me going back to the original code I had, not the code that was suggested by scragar to wrap the onreadystatechange anonymous in order to capture the state from the outer.
Ok, I will try going back to what I had originally with the mods you have suggested |
|
#14
|
|||
|
|||
|
Ok close but no cigar. I get the error 'originalArgs.splice is not a function'. I think that's because arguments is an array-like object, but not an instance of array, isn't it? So I can't use array functions on it.
|
|
#15
|
|||
|
|||
|
Sorry, try this:
var originalArgs = Array.prototype.slice.call(arguments); |
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|