Reputation: 83
Using the following code, the result was displayed successfully.
window.onload = setInterval(func_name, 5000);
function func_name() {
var ids = document.getElementById('aa').value;
ids_array = ids.split(',');
for (var i in ids_array) {
if (document.getElementById('a' + ids_array[i])) {
document.getElementById('a' + ids_array[i]).innerHTML = ids_array[i];
However, when I used an AJAX request instead, I get the error: TypeError: document.getElementById(...) is null
.
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById('a' + ids_array[i]).innerHTML = xmlhttp.response; // error is here... TypeError: document.getElementById(...) is null
}
}
xmlhttp.open("GET", "<?php echo baseurl . 'notification.php';?>?users_id=" + ids_array[i], true);
xmlhttp.send();
}
}
}
}
i am beginner, sorry for this type of code
Upvotes: 2
Views: 1032
Reputation: 48
Your ids_array[i] variable is not correctly defined in xmlhttp.onreadystatechange=function(), because "i" variable redefines with every FOR cycle iteration.
So all code should be:
var ids = document.getElementById('aa').value;
var ids_array = ids.split(',');
for (var i=0; i<ids_array.length; i++)
{
if (document.getElementById('a' + ids_array[i])) {
// For every iteration, create a closure that
// stores the "i" variable multiple times with different values in the closure.
// Also create an xmlhttp Object for each request.
var closure = function()
{
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById('a' + ids_array[i]).innerHTML = result;
// After this function executes, it and any closures it has will be
// available for garbage collection.
}
}
xmlhttp.open("GET", "<?php echo baseurl . 'notification.php';?>?users_id=" + ids_array[i], true);
xmlhttp.send();
// This code ends, but xmlhttp objects wait for onreadystatechange event.
}
}
}
I suggest you to read more about closures.
Upvotes: 1
Reputation: 71939
There are sevelral problems with your code. First, there is an extra }
at the end. Also, window.onload = setInterval(func_name, 5000);
should be:
window.onload = function() {
setInterval(func_name, 5000);
}
Then, for (var i in ids_array)
should be
for(var i=0; i<ids_array.length; i++) { ...
This could be part of your problem. For several reasons, your current loop may not work as you'd expect.
Finally, Ajax is asynchronous. The function you assign to xmlhttp.onreadystatechange
will only run after the loop has finished, and the value of i
will be the last value in the array (in your current code), or the length of the array (in the new version I proposed). The shortest fix looks like this:
xmlhttp.onreadystatechange = (function(i) {
return function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById('a' + ids_array[i]).innerHTML = xmlhttp.response; // error is here... TypeError: document.getElementById(...) is null
}
}
}(i));
More explanation about why can be found at JavaScript closure inside loops – simple practical example
I realized one more thing: to fire multiple requests like that, you need multiple XMLHttpRequest objects. I suggest using a separate function to start the ajax requests, like this:
function func_name() {
var ids = document.getElementById('aa').value;
ids_array = ids.split(',');
for(var i=0; i<ids_array.length; i++) {
if (document.getElementById('a' + ids_array[i])) {
(function(i) {
callAjax("<?php echo baseurl . 'notification.php';?>?users_id=" + ids_array[i], function(response){
document.getElementById('a' + ids_array[i]).innerHTML = response;
});
}(i));
}
}
}
function callAjax(url, callback) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
callback(xmlhttp.responseText);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
Upvotes: 2
Reputation: 37526
You didn't post any details about where the browser was reporting the problem (line of code), but my guess would be this:
var ids = document.getElementById('aa').value;
The most likely culprit is that you have no element with an id (id="aa"
) of aa
. Either that or you did something bizarre like this:
document = ...
somewhere in your code. That it's null
rather than undefined
is kind of weird.
Upvotes: 0