thesecretmaster thesecretmaster - 3 months ago 5
Javascript Question

Odd Contradictory Error

I have a heroku website with ruby, but my issue is with one page in particular. The issue with that page is javascript. The page also has ajax on it. Here is my page:

<!DOCTYPE html>
<html>
<head>
<script>
var refreshDelay = 5000000;
function createRequestObject() {
var ro;
if(navigator.appName == "Microsoft Internet Explorer"){
ro = new ActiveXObject("Microsoft.XMLHTTP");
}else{
ro = new XMLHttpRequest();
}
return ro;
}
var http = createRequestObject();
function sndReq() {
var newParent = document.getElementById('2');
var oldParent = document.getElementById('target');

while (document.getElementById('target').childNodes.length > 0) {
newParent.appendChild(document.getElementById('target').childNodes[0]);
}
http.open('post', '/chatContent?n=<%=@name%>');
http.onreadystatechange = handleResponse;
http.send(null);
}
function handleResponse() {
var newParent = document.getElementById('2');
var oldParent = document.getElementById('target');

while (document.getElementById('target').childNodes.length > 0) {
newParent.appendChild(document.getElementById('target').childNodes[0]);
}
if(http.readyState == 4){
var response = http.responseText;
document.getElementById('target').innerHTML = response;
setTimeout(sndReq(), refreshDelay);
}
}
setTimeout(sndReq(), refreshDelay);
</script>
<script>
scrollDown = function() {
document.body.scrollTop = document.body.scrollHeight;
}
</script>
</head>
<body onload='scrollDown()'>
<div id='2'>
</div>
<div id='target'>
<%=@chat%> <!-- @chat is a variable from my ruby file -->
</div>
<form action="/addChat?n=<%=@name%>" method='post'>
<input name='nchat' type='text' autofill='no' style='width:100%;height:10em;vertical-align:top'>
<input type='submit'>
</form>
<a href='/home'>Go home!</a>
</body>
</html>


When I load the page, it gives me this error in the console regarding line 24:

Uncaught TypeError: Cannot read property 'childNodes' of null


But when I enter into the console
document.getElementById('target').childNodes.length
it gives me however many nodes there are (it changes dynamically). What is going on??

Any extra things you want to see to answer this question I will try to promptly post. Just ask!

Answer

You are calling setTimeout(sndReq(), refreshDelay); which will execute sndReq() immediately because of the way you pass the function to setTimeout.

Since your sndReq() is in your head, the HTML will not have fully loaded yet so you are receiving the selector error because the element doesn't exist (yet).

You can change setTimeout(sndReq(), refreshDelay); to setTimeout(sndReq, refreshDelay); to pass the function reference to setTimeout so sndReq() doesn't fire immediately.

Ref: setTimeout