0

I'm doing a project for school and so far it's been a lot of copy this script and paste it here to make things "work". I don't really have any idea what I'm doing besides comparing one line of code to another and looking for the differences.

I've got javascript that is returning some values to me and it works fine when it's in a simple webpage format but when I insert it into a more complicated page it stops working.

At the very end of the page it should give a line of numeric values and be updated every 1000 milliseconds but what happens is it just sits there displaying Temp()...

I've checked the data.xml and those values are being updated when I push buttons and stuff on my PIC protoboard.

I'm using the same ajax.js file for both the simple webpage and the complicated page. I'm thinking it is something simple like a missed </p> or </div> tag but my eyes don't seem to see it.

Could some take a look at the code and see what I've missed? Thanks!

ajax.js

        var xhr;

        function getXMLHttpRequest(){

        try { return new ActiveXObject("Msxm12.XMLHTTP"); } catch(e){}; 
        try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e){};  
        try { return new XMLHttpRequest(); } catch(e){};    

        return null;
        }

        function parseHttpResponse(){

            if(xhr.readyState == 4){

                if(xhr.status == 200){

                document.getElementById("T0").innerHTML=xhr.responseText;
                }
                else
                {

                }
            }
        }

        function getTemp(){
        xhr = getXMLHttpRequest();

        xhr.open("GET", "data.xml", true);
        xhr.onreadystatechange = parseHttpResponse;
        xhr.send(null);
        }



        setInterval("getTemp()", 1000);

Simple webpage - this works great

            <html>
        <head><title>Ajax test - index1</title>

        <script src="ajax.js" type="text/javascript">
        </script>

        </head>

        <body onload="getTemp();">
            <h2>Headline</h2>
            <p>Paragraph</p>
            <div id='T0'>Loading Temp0...</div> 
        </body>
        </html>

"Complicated" webpage - when this is used I get no joy

                <!DOCTYPE html>
            <html>
            <head>
            <title>Elex267-Webpage</title>

            <script src="ajax.js" type="test/javascript">
            </script>

            <link rel="stylesheet" href="myStyle.css" type="text/css" >



            </head>

            <body onload="getTemp();">
            <!-- Banner at Top of Page ***********************************-->
            <div style="background-color:blue; color:white;font-size:30px;">

            <img src="Pics/camosun-white.png" alt="CamosunPNG" width="200" height="70" align="left">
            <div align="center"style="margin-left:50%">Elex 267 Web Demo
            <br>
            Microchip TCP/IP Stack v3.02</div>
            </div>
            <!--*********************************************************-->
            <!--NavBar Code *********************************************-->
            <div class="nav">
            <ul>
            <li><a href="index.htm">Home</a></li>
            <li><a href="features.htm">Features</a></li>
            <li><a href="about.htm">About</a></li>
            </ul>
            </div>
            <!--***************************************************-->
            <p>
            Welcome to the Elex 267 Demo Web Server for [Name Here].<br>
            </p>
            <p>
            This web page is being run on the NM101 NorthMicro Pic Prototype Board with the LCD/Keypad and Network modules.
            <br>
            This web page refreshes the data every 3 seconds.
            </p>
            <center>
            <img border="5" src="http://www.northmicro.com/GFX/nm110nm120onproto.jpg" alt="NM110 Proto Pic" width="200" height="200" >
            </center>
            <br>
            <div id="feedback" style="width:500px;float:left;">
            &nbsp;&nbsp;&nbsp;&nbsp;Pot RA0:   1022 <br>
            &nbsp;&nbsp;&nbsp;&nbsp;Pot RA1:   223 
            <br><br>
            &nbsp;&nbsp;&nbsp;&nbsp;Switch RA2: <img src="Pics/SwitchUp.gif" alt="SwitchOff" width="20" height="20" align="top">
            <br><br>
            &nbsp;&nbsp;&nbsp;&nbsp;LEDs:&nbsp;&nbsp;RB6  <img src="Pics/LEDOff.gif" alt="LED_Off" width="20" height="20" align="top"> &nbsp;&nbsp;RB5   <img src="Pics/LEDOn.gif" alt="LED_On" width="20" height="20" align="top">  
            </div>

            <div id="input" style="width=50%;margin-left:50%;">
            <b>Commands</b><br>
            <button align="left" type="button" onclick="alert ('RB5 Activated')">Toggle RB5</button>
            <br>
            <button align="left" type="button" onclick="alert ('RB6 Activated')">Toggle RB6</button>
            </div>
            <br><br>
                <div id='T0'>Loading Temp0...</div> 
            </body>
            </html>
mwolfetech
  • 1,516
  • 12
  • 22
Chef Flambe
  • 885
  • 2
  • 15
  • 35
  • Don't know what your problem is but did you check the console for errors? Are you sure you ajax request was made, because this could be a problem of asynchronous loading. – bitoiu Nov 18 '12 at 01:42
  • 2
    "I'm thinking it's something simple like a missed /p or /div but my eyes don't seem to see it." That's why you better use a code editor like Netbeans or Eclipse. I suppose you are using notepad++ or something. And use a web debugger like Google inspector or Firebug. Your getTemp() is called twice, one from onload, one from setInterval could cause unexpected behavior – Thanh Trung Nov 18 '12 at 01:44
  • It works fine if the simple webpage is being used. It just stops when the more complex page is loaded into my PIC. – Chef Flambe Nov 18 '12 at 01:47
  • put your getTemp() in a script tag at the end of your file (right before the ending body tag. At expressed here http://stackoverflow.com/questions/10494620/when-does-a-body-onload-gets-called, the onload trigger your function after everything is loaded (image included). Maybe it does get trggerd, but at the wrong time. – Louis Loudog Trottier Nov 18 '12 at 01:52
  • as mentioned by Thanh Trung, there is great tools meant to be used. They are free too and open-sources as well. – Louis Loudog Trottier Nov 18 '12 at 01:53
  • @LouisLoudogTrottier The location of the getTemp() *declaration* is irrelevant; `onload` code will not be executed until the document has been loaded, so always after the declaration. The problem is the location of the getTemp() *call*. – PointedEars Nov 18 '12 at 02:03
  • onload will trigger after all dom elements are ready, img included, maybe he's just not waitng long enough for the pic to show up.... as the script tag at the end will trigger when readed... I've tested and i have an 600ms difference bewteen an ending script tag and my onload trigger (without img) – Louis Loudog Trottier Nov 18 '12 at 02:14
  • i agree that it might not be his issue here but it can help finding where (or WHEN) it breaks – Louis Loudog Trottier Nov 18 '12 at 02:15
  • @LouisLoudogTrottier `onload` code will be triggered after the document code has been parsed. Resources like images may be finished later. This is implementation-dependent. As for the time difference: Again, that is interesting but irrelevant. Whether you *declare* the function in the document head or in the body has no bearing on the availability of the function in `onload` code or in `load` event listeners in general. You must be confusing this with something else. – PointedEars Nov 18 '12 at 02:18
  • Quoted from: https://developer.mozilla.org/en-US/docs/DOM/window.onload "The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading. There are also Gecko-Specific DOM Events like DOMContentLoaded and DOMFrameContentLoaded (which can be handled using element.addEventListener()) which are fired after the DOM for the page has been constructed, but do not wait for other resources to finish loading." w3school don'T say the same thing tho... :S – Louis Loudog Trottier Nov 18 '12 at 02:23
  • @LouisLoudogTrottier There is more to Web development than quoting documentation, particularly a wiki like *Mozilla* Developer Network. AISB, it is implementation-dependent and has nothing to do with function declaration. Delete W3Schools from your bookmarks while you are at it. – PointedEars Nov 18 '12 at 02:34
  • W3Schools is crap?! So THAT'S my problem...friggin' instructor is telling us to go there for the tutorials and muddle our way through things. Such a lame instructor. – Chef Flambe Nov 18 '12 at 02:43
  • sorry but i wans't trying to be a b. I just remembered seeing this article when i was having simlar issues.Stopped using onload with ajax since. and yes w3school is not a reliable sources. – Louis Loudog Trottier Nov 18 '12 at 02:45
  • I am afraid that while the intention of W3Schools may be good, there is too much misinformation there to be useful, particularly to beginners who necessarily cannot easily tell nonsense apart. IMHO, the amount of unlearning you would have to do is not worth it. (It is _not_ W3C.) You should start at MDN; but take everything in this field, particularly on the Web, with a handful of salt. Do not rely on what you read, test it yourself, in as many environments as possible (because implementations differ). I can also strongly recommend reading `comp.lang.javascript`; but it is not for the timid. – PointedEars Nov 18 '12 at 02:56

1 Answers1

2
setInterval("getTemp()", 1000);

does not make sense at this line, and it might be the cause of your problems. This call causes getTemp to be called every second, starting from after this call as returned. In the getTemp function you are reusing the xhr variable, creating a new XMLHttpRequest instance each time. That alone is not necessarily a problem (aside from the "Msxm12.XMLHTTP" which appears to be wrong; should probably be "Msxml2.XMLHTTP").

But in each call of getTemp you are issuing a new request, regardless if the previous request has received a response (the third argument being true means asynchronous request-response handling). Consider this: The readystatechange listener might not have been called (or its readyState == 4 part has not be executed) because the client is waiting for the server to respond. Now your one-second timer kicks in, calls getTemp again and thus overwrites the xhr value that is to be used in the listener code. There is a closure, xhr is a bound variable, and therefore there is a race condition already.

Further, an HTTP client SHOULD NOT (per RFC 2616), and a well-designed Web browser will not, keep more than a specified number of persistent HTTP connections (default: 2 to 8) open to the same server or proxy. So the more complex the document, and the more resources need to be loaded in parallel, the more likely that this approach will fail.

You should remove the setInterval(…) call and add a getTemp() call below the line where you update the innerHTML property (when the request was successful, status == 200), so that only then a new request is issued. You should at least wait for the readyState to become 4 (FINISHED) before you issue a new request. Since you want to wait one second before the next call, use window.setTimeout("getTemp()", 1000).

It should help your understanding if you pretty-print that code, that is, indent function body and block content with a reasonable amount of white-space, and add some white-space, for example between ) and {. There are editors like Eclipse JavaScript Development Tools which can automate much of the code formatting.

Afterwards you should learn to use a debugger (use Firebug for Firefox, newer versions of other browsers have one built-in) and set breakpoints in your code, particulary in getTemp and parseHttpResponse. Step through the code (caveat: step over send(), then continue so that execution halts at the breakpoint in parseHttpResponse) to see what is going on. Good luck.

PointedEars
  • 14,752
  • 4
  • 34
  • 33
  • Do not pass a string to `setInterval` or `setTimeout`. –  Nov 18 '12 at 02:49
  • Why? We do not need another closure here, so I saw no good reason to complicate the original code for this beginner. I sincerely hope that was not the reason for the downvote. – PointedEars Nov 18 '12 at 02:59
  • Proper syntax is `setTimeout(getTemp, 1000);`. How is that more complicated? –  Nov 18 '12 at 03:15
  • Utter nonsense. Have you read this in one of the many bad books on this topic? *Both* forms are possible (none of them is standardized, because the method itself is proprietary to date); the string argument is more compatible (although it is slightly slower). And `setTimeout(…, 1000)` is _not_ equivalent to `setTimeout("…", 1000)` in all cases. The string argument was in the original code, and it did no harm whatsoever. So I left it that way in my answer, avoiding further confusion. – PointedEars Nov 18 '12 at 04:34
  • For further reference, the most complete documentation on this method: [window.setTimeout at MDN](https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout) (CAVEAT: It's a wiki.) – PointedEars Nov 18 '12 at 04:47
  • I took the time to read *your reference* on MDN. In the **Notes** of *your reference* under the title 'Passing string literals' it says what you have done is 'incorrect'. –  Nov 18 '12 at 16:45
  • That's why I pointed out that MDN is a *wiki*. It's of course *not incorrect* to pass a string (it says at the top that that is *not recommended*, and why). The example at MDN is bogus at best (I might fix that later). As you can read there, the rationale for not passing a string value is that it is slow as `eval()`. However, speed does not matter here (it would e.g. for an animation). And *again*, the *original code* already used strings, and actually there are cases when it is *better* to pass a string. But that is well beyond the scope of this question, so would you *please* give it a rest. – PointedEars Nov 18 '12 at 20:37
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19719/discussion-between-pointedears-and-shaun5) – PointedEars Nov 18 '12 at 20:37