1

This is currently my javascript code:

function GetEvents()
{   
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange  = function()
{
    if (this.readyState == 4 && this.status == 200) 
    {
        var eventObjects = JSON.parse(this.responseText);

        var table = document.getElementById("EventsTable"); //Gets the Table in the HTMl
        //Loops through the passed in array and adds each event in the table
        for(i = 0; i < eventObjects.length; i++)
        {
            var startDate = new Date(eventObjects[i].eventStart);
            var eventStart = startDate.getDate() + " / " + startDate.getMonth() + " / " + startDate.getFullYear();
            var ID  = eventObjects[i].eventID;

            var row = table.insertRow(1);
            var cell1 = row.insertCell(0);
            var cell2 = row.insertCell(1);
            var cell3 = row.insertCell(2);
            cell1.innerHTML = eventObjects[i].eventName;
            cell2.innerHTML = eventStart;
            cell3.addEventListener("click", function(){GetEventInfo(ID); });

            //Adds Image to third cell;
            var img = document.createElement('img');
            img.src = "EventIcon.png"
            cell3.appendChild(img); 
        }           
    }
}
xmlhttp.open("GET", "php/includes/GetEvents.php", true);
xmlhttp.send();
}

function GetEventInfo(eventID)
{
    alert(eventID);
}

Looking at the first function, what it's doing is inserting cells into a HTML file that I have which is used to display information about events, using data gathered from my database. This works fine though what I'm currently trying to do is for the second function to be called when I click on one of these events in the table, passing in a eventID which each event should have.

The eventID number for each event is also gathered from the database so what I'm trying to do now is add a onclick action to each event which will run the "GetEventInfo" function and pass in the corresponding events ID. So far I've got a varaible holding the ID:

var ID  = eventObjects[i].eventID;

and then I'm using this to add the onclick action:

cell3.addEventListener("click", function(){GetEventInfo(ID); });

This does the onclick stuff correctly, the events runs the function when I click on them but the problem I'm having is that the ID that is passed in is the exact same for each event, so no matter what event I click on, it will always print out the same Event ID which it shouldn't, that eventID either being the first or last event.

Does anyone have any idea on why this is happening?

codelyoko373
  • 141
  • 1
  • 9

1 Answers1

1

All var variables get hoisted - it has function scope, so once all iterations are finished, every ID references the last ID you assigned.

To the interpreter, it effectively looks like this:

xmlhttp.onreadystatechange  = function()
{
var ID;
// ...
// ...
  // <start for loop>
    ID  = eventObjects[i].eventID;
    // ...
    cell3.addEventListener("click", function(){GetEventInfo(ID); });

Use const instead:

const ID = eventObjects[i].eventID;

Try not to use var, it makes reasoning about code difficult. Use const and let instead, since they have block scope and aren't hoisted. If you have to support ancient browsers that don't recognize ES2015 syntax, use Babel to transpile your code to ES2015 - after you've written it.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320