By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,978 Members | 1,771 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,978 IT Pros & Developers. It's quick & easy.

repeated XMLHttpRequest GETs and displaying result

P: n/a
I'm a bit new to javascript - as will be obvious below.

I'm using an XMLHttpRequest to get a bit of data from server (django),
and it works nicely for single events. But my eventual outcome needs
to be a series of data transmissions. I figured requesting data over
and over until the data is some value that triggers the stop would be
an interesting first attempt. To move forward, I wrapped my initial
single data request in a for-loop to see if I could do multiple calls.

Here's my javascript stuff...

Expand|Select|Wrap|Line Numbers
  1. for (i=0;i<=5;i++) {
  2. xmlHttp.onreadystatechange=function()
  3.  
  4. { if (xmlHttp.readyState==4)
  5. { document.myForm.myvar.value=xmlHttp.responseText;
  6. }
  7. }
  8. xmlHttp.open("GET","/ajax_data",true);
  9. xmlHttp.send(null);
  10.  
  11. //alert("got here")
  12. dopause(500);        //wait 500ms
  13. }
What I've noticed is that with that alert line commented out, nothing
seems to happen -ie I don't see the data receive. I expected to see
it flash 5 times (the server sends a random number)

When I put the alert in, the alert does in fact pop up, and the data
gets displayed.

Does the alert message cause a window refresh that I need to emulate
when the alert is not there. What do I need to do to make it cycle
through the get 5 times and actually show me what comes up, WITHOUT
using an alert pop!?

Thanks for any suggestions
Jun 27 '08 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On Jun 25, 2:44*pm, RossGK <ros...@gmail.comwrote:
I'm a bit new to javascript - as will be obvious below.

I'm using an XMLHttpRequest to get a bit of data from server (django),
and it works nicely for single events. *But my eventual outcome needs
to be a series of data transmissions. *I figured requesting data over
and over until the data is some value that triggers the stop would be
an interesting first attempt. *To move forward, I wrapped my initial
single data request in a for-loop to see if I could do multiple calls.

Here's my javascript stuff...

* * * * for (i=0;i<=5;i++) {
* * * * * * * * xmlHttp.onreadystatechange=function()

* * * * * * * * { if (xmlHttp.readyState==4)
* * * * * * * * * * * * { document.myForm.myvar.value=xmlHttp.responseText;
* * * * * * * * * * * * }
* * * * * * * * }
* * * * * * * * xmlHttp.open("GET","/ajax_data",true);
* * * * * * * * xmlHttp.send(null);

* * * * * * * * //alert("got here")
* * * * * * * * dopause(500); * * * *//wait 500ms
* * * * * }

What I've noticed is that with that alert line commented out, nothing
seems to happen -ie I don't see the data receive. *I expected to see
it flash 5 times (the server sends a random number)

When I put the alert in, the alert does in fact pop up, and the data
gets displayed.

Does the alert message cause a window refresh that I need to emulate
when the alert is not there. *What do I need to do to make it cycle
through the get 5 times and actually show me what comes up, WITHOUT
using an alert pop!?

Thanks for any suggestions
Wish I could test this, but I don't have the resources. I'm assuming
the myvar is a text field or text area in your form? Try appending
the responsetext to this section - not just setting it (not as a
permanent solution, mind you, but just to debug). It may be being
overwritten with a null response.
Jun 27 '08 #2

P: n/a
Wish I could test this, but I don't have the resources. I'm assuming
the myvar is a text field or text area in your form?

Yes, the text gets assigned to myvar in the form below...

<form name="myForm">
Stuff: <input type="text" onkeyup="getServerData();" name="username" /
>
Response: <input type="text" name="myvar" />
</form>

.... and as I say works nicely in a single event, or with the alert
pop.
Try appending the responsetext to this section - not just setting it (not as a
permanent solution, mind you, but just to debug). It may be being
overwritten with a null response.
Not sure what you mean... do you mean like some sort of print
statement? (sorry my javascript weakness is showing)....
Jun 27 '08 #3

P: n/a
On Jun 25, 3:44*pm, RossGK <ros...@gmail.comwrote:
Wish I could test this, but I don't have the resources. *I'm assuming
the myvar is a text field or text area in your form?

Yes, the text gets assigned to myvar in the form below...

<form name="myForm">
* * * * Stuff: <input type="text" onkeyup="getServerData();" name="username" /

* * * * Response: <input type="text" name="myvar" />
</form>

... and as I say works nicely in a single event, or with the alert
pop.
Try appending the responsetext to this section - not just setting it (not as a
permanent solution, mind you, but just to debug). *It may be being
overwritten with a null response.

Not sure what you mean... do you mean like some sort of print
statement? *(sorry my javascript weakness is showing)....
Try document.myForm.myvar.value+=xmlHttp.responseText;

instead of

document.myForm.myvar.value=xmlHttp.responseText;
Jun 27 '08 #4

P: n/a
On Jun 25, 3:46 pm, after9 <ggama...@gmail.comwrote:
>
Try document.myForm.myvar.value+=xmlHttp.responseText;

instead of

document.myForm.myvar.value=xmlHttp.responseText;
Same behaviour results. When I keep the alert box in there, I see the
data get appended successively to the the previous data, and the form
field fills up. Without the alert box, nothing shows up.

Looking at my server log, interestingly I notice each time the alert
pops up, the data is displayed and I dismiss the alert, the server
shows that it has received a request and sent the data.

Without the alert box, the server shows only one request (and nothing
shows up on my page). So it seems the for-loop doesn't succeed in
making multiple requests without the alert box.

Will have to puzzle over that a bit longer...
Jun 27 '08 #5

P: n/a
On Jun 25, 4:02 pm, RossGK <ros...@gmail.comwrote:
On Jun 25, 3:46 pm, after9 <ggama...@gmail.comwrote:
Try document.myForm.myvar.value+=xmlHttp.responseText;
instead of
document.myForm.myvar.value=xmlHttp.responseText;

Same behaviour results. When I keep the alert box in there, I see the
data get appended successively to the the previous data, and the form
field fills up. Without the alert box, nothing shows up.

Looking at my server log, interestingly I notice each time the alert
pops up, the data is displayed and I dismiss the alert, the server
shows that it has received a request and sent the data.

Without the alert box, the server shows only one request (and nothing
shows up on my page). So it seems the for-loop doesn't succeed in
making multiple requests without the alert box.

Will have to puzzle over that a bit longer...
I can't see all your code, but it appears to me that without the pause
in there, you are reassigning the xmlhttprequest before it was
completed. You need to launch separate instances of xmlhttprequest,
rather than successively firing off the same one before it has
received a response. Know what I mean?
Jun 27 '08 #6

P: n/a
RossGK escribió:
Expand|Select|Wrap|Line Numbers
  1.     for (i=0;i<=5;i++) {
  2.         xmlHttp.onreadystatechange=function()
I'm not sure about your code (that's what frameworks have, you need to
be familiar with them) but it seems you only have one XMLHttp object and
you are overwriting its onreadystatechange handler on every loop
interation. I suppose only the last one works :-?

If you need to perform 6 simultaneous calls you need 6 separate
instances of your XMLHttp object type:

Expand|Select|Wrap|Line Numbers
  1. // Untested!
  2. function YourXMLHttpObject(){
  3. // ...
  4. this.onreadystatechange = function(){
  5. //...
  6. }
  7. }
  8.  
  9. var calls =[];
  10. for(var i=0; i<6; i++){
  11. var xml = new YourXMLHttpObject;
  12. xml.foo = bar;
  13. //...
  14. calls.push(xml);
  15. }

Expand|Select|Wrap|Line Numbers
  1.         { if (xmlHttp.readyState==4)
  2.             { document.myForm.myvar.value=xmlHttp.responseText;
  3.             }
  4.         }
  5.         xmlHttp.open("GET","/ajax_data",true);
  6.         xmlHttp.send(null);
  7.  
  8.         //alert("got here")
  9.         dopause(500);        //wait 500ms
I don't know who dopause() works but, in general, I've found sleep()
clones of little help in JavaScript development (just an opinion).



--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://bits.demogracia.com
-- Mi web de humor al baño María: http://www.demogracia.com
--
Jun 27 '08 #7

P: n/a
On Jun 26, 11:28 am, "Álvaro G. Vicario" wrote:
RossGK escribió:
> for (i=0;i<=5;i++) {
xmlHttp.onreadystatechange=function()

I'm not sure about your code (that's what frameworks have, you
need to be familiar with them)
?
but it seems you only have one XMLHttp object and
you are overwriting its onreadystatechange handler on
every loop interation. I suppose only the last one works :-?

If you need to perform 6 simultaneous calls you need 6
separate instances of your XMLHttp object type:
<snip>

But making 6 simultaneous calls is not what the OP wants; it is one of
the mistakes being made (and the HTTP limit on the number of
simultaneous connections to the server (which is 2) would make that
difficult to say the least (even if some browsers disregard that
limit)). 6 calls in sequence seems to be (nearer) what is wanted,
which implies the - onreadystatechange - handler arranging a
subsequent request, for which a single XML HTTP request object would
be sufficent.
Jun 27 '08 #8

P: n/a
On Jun 25, 4:33*pm, Tom Cole <tco...@gmail.comwrote:
I can't see all your code, but it appears to me that without the pause
in there, you are reassigning the xmlhttprequest before it was
completed. You need to launch separate instances of xmlhttprequest,
rather than successively firing off the same one before it has
received a response. Know what I mean?
Understood, but that's why I had put in a little sleep function to
give the request a chance to come back before firing it off again.

The doPause is a simple loop...

Expand|Select|Wrap|Line Numbers
  1. function dopause(msecs)
  2. {var date = new Date();
  3. var nowDate= null;
  4.  
  5. do { nowDate= new Date(); }
  6. while(nowDate-date < msecs);
  7. }
So given that there IS a pause happenging between requests, it seems
like the alert box causes the equivalent of a screen 'repaint'...but
if that was the case I'd see the last one... and I don't. In fact,
the server side reports indicate only one request then a stall.

R.
Jun 27 '08 #9

P: n/a
On Jun 26, 7:01*am, Henry <rcornf...@raindrop.co.ukwrote:
On Jun 26, 11:28 am, "Álvaro G. Vicario" wrote:
RossGKescribió:
* *for (i=0;i<=5;i++) {
* * * * * *xmlHttp.onreadystatechange=function()
I'm not sure about your code (that's what frameworks have, you
need to be familiar with them)

?
but it seems you only have one XMLHttp object and
you are overwriting its onreadystatechange handler on
every loop interation. I suppose only the last one works :-?
If you need to perform 6 simultaneous calls you need 6
separate instances of your XMLHttp object type:

<snip>

But making 6 simultaneous calls is not what the OP wants; it is one of
the mistakes being made (and the HTTP limit on the number of
simultaneous connections to the server (which is 2) would make that
difficult to say the least (even if some browsers disregard that
limit)). 6 calls in sequence seems to be (nearer) what is wanted,
which implies the - onreadystatechange - handler arranging a
subsequent request, for which a single XML HTTP request object would
be sufficent.
Thanks for that followup. I would be worried about a proliferation of
calls, and sequencing issues. While if I use the same one, ensuring it
finishes before refiring (onreadystatechange) it seems safer, that I
won't have some network congestion returning request 3 after request 5
or something.

I guess the difference is that I'd like sequential calls rather than
simultaneous calls

?
Jun 27 '08 #10

P: n/a
RossGK wrote:
On Jun 25, 4:33 pm, Tom Cole <tco...@gmail.comwrote:
>I can't see all your code, but it appears to me that without the pause
in there, you are reassigning the xmlhttprequest before it was
completed. You need to launch separate instances of xmlhttprequest,
rather than successively firing off the same one before it has
received a response. Know what I mean?

Understood, but that's why I had put in a little sleep function to
give the request a chance to come back before firing it off again.

The doPause is a simple loop...

Expand|Select|Wrap|Line Numbers
  1. function dopause(msecs)
  2.     {var date = new Date();
  3.      var nowDate= null;
  4.  
  5.      do { nowDate= new Date(); }
  6.      while(nowDate-date < msecs);
That is probably the worst thing you can do. Especially in a
single-threaded environment like this.

As it was said before, you need to start the next request in the
onreadystatechange event listener of the previous one. Quick hack:

Expand|Select|Wrap|Line Numbers
  1. // add feature tests and alternatives here
  2. var xhr = new XMLHttpRequest();
  3.  
  4. // suppose you are within a block statement already;
  5. // else use a function *declaration* instead
  6. var f = function() {
  7. if (xhr.readyState == 4)
  8. {
  9. if (!stopCriteria)
  10. {
  11. // wait for a while before the next request
  12. // so we are not "hammering"; add feature tests here
  13. var t = window.setTimeout(
  14. function() {
  15. window.clearTimeout(t);
  16. t = null;
  17. xhr.open("GET", "http://bar.example", true);
  18. xhr.onreadystatechange = f;
  19. xhr.send(...);
  20. },
  21. 1000);
  22. }
  23. };
  24.  
  25. xhr.open("GET", "http://foo.example", true);
  26. xhr.onreadystatechange = f;
  27. xhr.send(...);
I think I have posted something similar here before.


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
Jun 27 '08 #11

P: n/a

Thanks for the comments. Not sure I'm any closer to my goal, but there
are some things to explore in the postings and in my further JS ramp up...
Jun 27 '08 #12

P: n/a
Expand|Select|Wrap|Line Numbers
  1. <html><head><script>
  2. window.onload= function () {
  3. var x= function (p) { return document.getElementById(p) },
  4. xmlHttp= new XMLHttpRequest();
  5. xmlHttp.i= 5;
  6. xmlHttp.onreadystatechange= function () {
  7. if (xmlHttp.readyState === 4) {
  8. x('id').innerHTML= (xmlHttp.i--)+": "+xmlHttp.responseText;
  9. setTimeout(xmlHttp.doItAgain, 500);
  10. }
  11. };
  12. (xmlHttp.doItAgain= function () {
  13. if (xmlHttp.i) {
  14. xmlHttp.open("GET","/ajax_data",true);
  15. xmlHttp.send(null);
  16. } else {
  17. xmlHttp= undefined;
  18. }
  19. })();
  20. };
  21. </script></head><body><span id="id"></span></body></html>
On a Mac, works fine in Safari, FF2, Opera 9.5, but not in FF3 : the
second call to xmlHttp.send(null) does nothing (!), Why ?.

HTH,
--Jorge.
Jun 27 '08 #13

P: n/a
On Jun 27, 7:26*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>
Once you've seen an error message popping up when navigating away or a UA
leaking memory because of a timeout or interval not properly cleared, you
will see how wrong you are here.
I understand the need to clear a setInterval() timer, but not a
setTimeout() that has already timed out.
In which browser/browsers did you observe those leaks and/or error
messages ?
(IE, again ?)
Setting "t= null" (?) is 200% useless too.

I will look into that later.
And there's no need to assign the handler "xhr.onreadystatechange = f"
more than once: that line could be deleted as well.

Obviously you don't know how XHR is implemented.
Nope. I don't. But if you do, may you please explain why :
An nsIXMLHttpRequest::send() call clears all event listeners:
only in FF3... ?
<http://www.xulplanet.com/references/xpcomref/ifaces/nsIXMLHttpRequest...>
Thanks,
--Jorge.
Jun 27 '08 #14

P: n/a
Jorge wrote:
Thomas 'PointedEars' Lahn wrote:
>Once you've seen an error message popping up when navigating away or a UA
leaking memory because of a timeout or interval not properly cleared, you
will see how wrong you are here.

I understand the need to clear a setInterval() timer, but not a
setTimeout() that has already timed out.
How did you get that idea?
In which browser/browsers did you observe those leaks and/or error
messages ? (IE, again ?)
Yes, it was IE 6 in particular.
>>And there's no need to assign the handler "xhr.onreadystatechange = f"
more than once: that line could be deleted as well.
Obviously you don't know how XHR is implemented.

Nope. I don't. But if you do, may you please explain why :
>An nsIXMLHttpRequest::send() call clears all event listeners:

only in FF3... ?
Fx 2 exhibits the same behavior, and the Gecko source code shows why.
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Jun 27 '08 #15

P: n/a
In comp.lang.javascript message <g4*******************@news.demon.co.uk>
, Thu, 26 Jun 2008 23:56:16, Richard Cornford
<Ri*****@litotes.demon.co.ukposted:
> That undesirable routine would be more efficiently written as
function dopause(msecs) { var done = +new Date() + msecs;
while (new Date() < done) {} }

Is there any point in a CPU spinning its wheels more efficiently?
A shorter algorithm, where it works as well or better, is always an
improvement. This one illustrates the point that no work that can be
done outside a loop should be done within it (and unary +).

If you still have access to the FAQ, how about correcting Section 5?

--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk IE7 FF2 Op9 Sf3
news:comp.lang.javascript FAQ <URL:http://www.jibbering.com/faq/index.html>.
<URL:http://www.merlyn.demon.co.uk/js-index.htmjscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/TP/BP/Delphi/jscr/&c, FAQ items, links.
Jun 27 '08 #16

P: n/a
On Jun 28, 12:42*am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>
Fx 2 exhibits the same behavior, and the Gecko source code shows why.
What ?
In Spain it runs fine in FF2, Opera and Safari... jejeje.
See : http://tinyurl.com/58tz3t

What's going on here ?

--Jorge.
Jun 28 '08 #17

P: n/a
On Jun 28, 10:58*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Yes, apparently Firebug when enabled modifies XHR enough so that it behaves
quite different than implemented. *Now that you mention it, I remember to
have seen several postings elsewhere that complained about XHR not properly
working when Firebug was enabled. *However, I have not seen and did not
expect it to mess with `onreadystatechange' as well. *Unfortunately, itis
still the same with Firebug 1.2.0b3.
Hmm, yeah, the code at http://tinyurl.com/58tz3t runs in FF3 as well,
as long as firebug is enabled.

I don't think that that's unfortunate, that's the way it should be. I
can't figure out what's (Mozilla's) excuse to arbitrarily null a
property of an object after it has been created and setup by my code.
There's no need to, and other browsers don't do it.

BTW, did you notice that "this" is setup differently in the
onreadystatechange callback, in FF2 ? it points to the XHR object in
Safari, Opera and FF3.

Bye,
--Jorge.
Jun 28 '08 #18

P: n/a
On Jun 28, 10:58*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
(...)
This and more is most obvious to everyone else but you,
(...)
Since I have no intention of repeating myself, I strongly suggest you learn
how to extract meaning from already posted texts.
(...)
Score adjusted
Thomas, Thomas. Eat your pills.

--Jorge.
Jun 28 '08 #19

P: n/a
On Jun 27, 3:42 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Jorge wrote:
Thomas 'PointedEars' Lahn wrote:
Once you've seen an error message popping up when navigating away or a UA
leaking memory because of a timeout or interval not properly cleared, you
will see how wrong you are here.
I understand the need to clear a setInterval() timer, but not a
setTimeout() that has already timed out.

How did you get that idea?
I don't see why calling clearTimeout there.
============================================
var t = window.setTimeout(
function() {
window.clearTimeout(t);
============================================

The callback function for setTimeout has already fired. What is the
purpose for calling clearTimeout? The variable - t - is not even
needed.

Garrett
PointedEars
Jun 29 '08 #20

This discussion thread is closed

Replies have been disabled for this discussion.