sunhearth
sunhearth

Reputation: 93

How to add event listener to each row of a table, and to pass a parameter with the function

I create dinamically a table of emails, and I would like to give to each row of this table an event listener so that I can click on each email. This is my code,

for(var i=0;i<emails.length;i++){
      let row = document.createElement('tr');
      row.addEventListener('click', () => email(emails[i].id));
      let cols = '<td>' + emails[i].recipients + '</td><td>' + emails[i].subject + '</td><td style="width:35%;"> ' + body + '</td><td>'+emails[i].timestamp+'</td>';
      row.innerHTML = cols;
      document.getElementById('table-body').appendChild(row);
}

Where emails is a Nodelist.

This is the table:

enter image description here

I'm receiving this error:

Uncaught TypeError: Cannot read property 'id' of undefined
    at HTMLTableRowElement.<anonymous> (inbox.js:56)

How can I solve this? Thank you!

Upvotes: 0

Views: 908

Answers (1)

patrickb
patrickb

Reputation: 442

A simple solution with ES6 - use let instead of var when defining the loop index variable.

This question has a lot of details about the why you're getting the undefined error as well as some alternative solutions. It boils down to the way that variables are scoped in javascript - var is scoped to the function, not the block as it is in a C-style language.

The below is a working example, though I did locally define some dummy data structures and swap out the email function for a console.log.

let body = "some email body";
let emails = [];
emails.push({id: "1", timestamp: "Some time", recipients: "person1, person2", subject: "Subject 1"});
emails.push({id: "2", timestamp: "Some time", recipients: "person2", subject: "Subject 2"});


for(let i = 0; i < emails.length; i++){
      let row = document.createElement('tr');
      row.addEventListener('click', function() {console.log(emails[i].id);});
      let cols = '<td>' + emails[i].recipients + '</td><td>' + emails[i].subject + '</td><td style="width:35%;"> ' + body + '</td><td>'+emails[i].timestamp+'</td>';
      row.innerHTML = cols;
      document.getElementById('table-body').appendChild(row);
}
<body>
  <table>
    <tbody id="table-body"></tbody>
  </table>
<body>

Upvotes: 1

Related Questions