In Firefox null gets assigned before XHR returns. Works in IE.

P

pbd22

Hi.

My below code works in IE but not in Firefox.
I think this is a aync vs. sync issue but I need some
clarification (and advice) here.

I have a function with the following code in it:

1. var myJSONtxt = GetChildCategories(parentID);
2. var json = JSON.parse(myJSONtxt);

In IE, the script waits for GetChildCategories to return
the JSON string before it executes line 2.

In Firefox, line 1 gets evaluated and moves on to line 2 before
the xmlhttp request object can return its value to myJSONtxt.
As a result "null" gets parsed and json throws all sorts of errors.

Can somebody please give me a "code example" of how I should
do this so it works in both IE and Firefox? I'd prefer non-library
based solutions. Below is the called function:

function GetChildCategories(parentID)
{
var xmlhttp=false;
var returnObj;

try {

//Show page is loading
document.getElementById('tabs-1').innerHTML = 'Loading
page Please wait... <img src="images/loading.gif">';

/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can
cope with old IE versions.
// and security blocked creation of the objects.
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {

try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp=false;
}
}
if (!xmlhttp && window.createRequest) {
try {
xmlhttp = window.createRequest();
} catch (e) {
xmlhttp=false;
}
}

var url = "trade.svc/getchildren/" + id;


xmlhttp.open("GET", url, false);

xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
if(xmlhttp.readyState == 4)
{
returnObj = xmlhttp.responseText;
}
}
}

xmlhttp.send(null)

} catch (e) { alert("E: " + e.message);}

return returnObj;

}
 
M

Martin Honnen

pbd22 said:
xmlhttp.open("GET", url, false);

xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
if(xmlhttp.readyState == 4)
{
returnObj = xmlhttp.responseText;
}
}
}

xmlhttp.send(null)

} catch (e) { alert("E: " + e.message);}

return returnObj;

You shouldn't use synchronous requests in the browser as they can block
the user interface. But if you do nevertheless then don't use an
onreadystatechange handler as Mozilla does not fire it in that case (not
sure about the latest Firefox/Mozilla version but FF 3.0 does not).
You don't need an onreadystatechange handler with a synchronous request
as the send() call blocks. So you can simply access xmlhttp.responseText
after the send() call.
 
M

Martin Honnen

Johannes said:
Martin Honnen :


Isn't that exactly what is wanted in some cases : to block the user until
there is a meaningful response on which she may act ?

If Javascript is run in the user interface thread and the synchronous
request blocks that thread then the user can't interact with the
browser. I don't think that is desirable.
 
G

Gregor Kofler

Johannes Baagoe meinte:
Martin Honnen :


Isn't that exactly what is wanted in some cases : to block the user until
there is a meaningful response on which she may act ?

No.

In the asynchronous case you can set a timeout limit, and respond in a
meaningful way, if the timeout occurs before a response has cleared the
timeout. Synchronous request that fail, will hang the browser (or the
tab) forever and leave the user swearing about the incompetence of the
web authors - at best. Normally, they'll jsut leave and never return.

Gregor
 
P

pbd22

Thanks.

If, by moving from synchronous to asynchronous, I am supposed
to change:

xmlhttp.open("GET", url, false);

to

xmlhttp.open("GET", url, true);

it still does not fix my problem. As for doing away with the
"onreadystatechange" function, could you please show me a code
illustration of how I am otherwise supposed to expose
xmlhttp.responseText?

At any rate, changing "false" to "true" still does not do anything. In
FF, by the time line 2 is evaluated, "json" is null.

1. var myJSONtxt = GetChildCategories(parentID);
2. var json = JSON.parse(myJSONtxt);

Could somebody please "show" me how to do this?

Thanks.
 
P

pbd22

Thanks.

If, by moving from synchronous to asynchronous, I am supposed
to change:

xmlhttp.open("GET", url, false);

to

xmlhttp.open("GET", url, true);

it still does not fix my problem. As for doing away with the
"onreadystatechange" function, could you please show me a code
illustration of how I am otherwise supposed to expose
xmlhttp.responseText?

At any rate, changing "false" to "true" still does not do anything. In
FF, by the time line 2 is evaluated, "json" is null.

1. var myJSONtxt = GetChildCategories(parentID);
2. var json = JSON.parse(myJSONtxt);

Could somebody please "show" me how to do this?

Thanks.
 
M

Martin Honnen

pbd22 said:
Thanks.

If, by moving from synchronous to asynchronous, I am supposed
to change:

xmlhttp.open("GET", url, false);

to

xmlhttp.open("GET", url, true);

it still does not fix my problem. As for doing away with the
"onreadystatechange" function, could you please show me a code
illustration of how I am otherwise supposed to expose
xmlhttp.responseText?

If you use asynchronous processing then you can't return the
responseText from the function that sends the request obviously as that
function is long finished when the onreadystatechange handler is called
with readyState being 4. So in that case you need to move your code
parsing responseText into the onreadystatechange handler or at least
into a function you call from the onreadystatechange handler.

In the case of a synchronous request the send() call blocks script
execution until the response is there so you can simply put a
return xmlhttp.responseText;
after your send() call, maybe additionally checking the status property
first.
 
G

Gregor Kofler

Johannes Baagoe meinte:
Gregor Kofler :


Is that so ? Is there no implicit and automatic timeout, with the standard
HTTP error 408 Request Timeout on reaching it with no response ?

No.

Gregor
 
R

Richard Cornford

Gregor Kofler :

Is that so ? Is there no implicit and automatic timeout, with the
standard HTTP error 408 Request Timeout on reaching it with no
response ?

And XML HTTP request that receives an HTTP response is not failing (at
least in by some definitions of failing).

Timeouts do happen with synchronous requests. How long various things
take to time out is very variable. For example, I once timed the
timeout for a request to a JSP server script that would
(theoretically) take 17 hours to gather the requested data before
starting to send its response. IE 6 timed out after four and a half
minutes of waiting, while the timeout for failing to connect to the
server is considerably shorter. As I recall, the timeout following
making a synchronous XML HTTP request and then pulling the network
cable out of the computer (which guarantees that the request will fail
(if done quickly enough)) is a couple of minutes on IE 6 and 7
(Windows 2000 and XP respectively).

Synchronous requests are a mistake. The supposedly beneficial side
effect of blocking the browser (and so not having design/create code
to handle multiple asynchronous sources of input, including the user)
end up being more than negated by the negative impact the unresponsive/
uninformative blocked UI has on the user's experience. The user's
don't know when, where (or why) or for how long they are going to have
to wait, and how long they will have to wait ends up being hostage to
the performance of networks/server, which are unlikely to be
consistent and rarely as good in the wild as they can be in
development environments.

Richard.
 
G

Gregor Kofler

pbd22 meinte:
Thanks.

If, by moving from synchronous to asynchronous, I am supposed
to change:

xmlhttp.open("GET", url, false);

to

xmlhttp.open("GET", url, true);

it still does not fix my problem. As for doing away with the
"onreadystatechange" function, could you please show me a code
illustration of how I am otherwise supposed to expose
xmlhttp.responseText?

You need to assign a function to onreadystatechange and *in* this
function you can access process your responseText (after of course
ensuring proper readystate (4) and status (2xx).
At any rate, changing "false" to "true" still does not do anything. In
FF, by the time line 2 is evaluated, "json" is null.

As expected.
1. var myJSONtxt = GetChildCategories(parentID);
2. var json = JSON.parse(myJSONtxt);

Could somebody please "show" me how to do this?

Sigh. Took me about 10 seconds to find an example from a relatively
trustworthy source (though some here might disagree):

https://developer.mozilla.org/En/Using_XMLHttpRequest


Gregor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,056
Messages
2,570,440
Members
47,101
Latest member
DoloresHol

Latest Threads

Top