onreadystatechange() missing on XMLHttpRequest objects
Solution 1
onreadystatechange
does exist...that's why it's null
. If it didn't exist, it would be undefined
. It all depends on whether it's been set already. It's clearly already a property because it's null
...if it weren't, it would be undefined
...or at least "onreadystatechange" in this
would be false
.
Here's an example:
var a = new XMLHttpRequest();
a.onreadystatechange = function () {
};
a.send();
Your console will log a function
.
If you had:
var b = new XMLHttpRequest();
b.send();
Your console would log null
.
Here's a demo of this happening: http://jsfiddle.net/3XKx7/
(I clearly left other steps out for sending an AJAX request, it was just for explanation)
I'm not trying to imply there's a relation between null
and undefined
- I'm just saying that when creating a new XMLHttpRequest
, the onreadystatechange
will be set to null
internally. Whether you set it to a function or not is up to you.
UPDATE:
The normal way for creating/sending an XHR is this order:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () { // This and `open` could be flip-flopped
// whatever
};
xhr.open("POST", url, true);
xhr.send("data=data");
I was always told/shown to create the new XMLHttpRequest
, then whatever order of setting onreadystatechange
and calling open
, but only after both of those should I call send
.
So, if that were always done, onreadystatechange
(if actually set) would not be null
and would be a function
.
Since you mentioned you were using jQuery, I decided to test with overriding the send
method like you want, and making a jQuery $.ajax
call (not sending a XMLHttpRequest
manually). Here's my testing - http://jsfiddle.net/3XKx7/1/
It doesn't make sense why onreadystatechange
would be null
, because jQuery has to be binding to that event in order to know when the request completes and its state. So I decided to look at the jQuery source code. And what I found was that the order they call things is:
xhr.open()
xhr.send()
xhr.onreadystatechange = function () {
};
Which means that when you're overriding the send
method, onreadystatechange
is null
since jQuery doesn't set it before calling send
. I don't know their reasoning for it...it might be to prevent things like what you're doing...but I never heard of or saw this convention being used.
So the reason you're getting its value as null
is because jQuery sets onreadystatechange
after calling send
. Meaning that when you override send
and try to access the onreadystatechange
property, it isn't set yet.
Hopefully this is an example that can help you understand: http://jsfiddle.net/dMP6q/16/
Solution 2
You're supposed to set it yourself, this function will be called when the state change. It's just like the other event handlers, like document.onload
, yourelement.onclick
, etc.
Classically you do
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
// use httpRequest.responseText
}
}
};
httpRequest.open('GET', url);
httpRequest.send();
Johan
Updated on June 27, 2022Comments
-
Johan almost 2 years
(function (send) { XMLHttpRequest.prototype.send = function () { console.log(this.onreadystatechange); //null send.apply(this, arguments); }; })(XMLHttpRequest.prototype.send);
Why is
this.onreadystatechange
null? According to this it should exist and be of typefunction
.