Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm waiting until the data has been retrieved and then adding the data to the table and (trying to) add a click event to each row with the following code.

scope.$watch(attrs.aaData, function(value) {
  var completeData = scope.$eval(attrs.allData);
  var dataTable = element.dataTable(options);
  var val = value || null;
  if (val) {
    dataTable.fnClearTable();
    dataTable.fnAddData(scope.$eval(attrs.aaData));
    var table = document.getElementsByClassName("dataTable")[1];
    for (var i = 0, row; row = table.rows[i]; i++) {
      console.log(row);
      console.log(completeData[i]);
      $(row).click(function(){
        window.location.hash = '#/dashboard/patients/' + completeData[i].patient_id;
      })
      // javascript for click, but there should be a ng-click way
      // $(row).attr('ng-click', 'changeView(/dashboard/patients/1)');
    };
  }

The console log confirms the row and completeData[i] are returning the correct values (and completeData[i]) has the patient_id component I want. Yet, when I click any row I get the following error:

Uncaught TypeError: Cannot read property 'patient_id' of undefined 

Any ideas?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

The issue is a scoping issue. You need to wrap your event handler in a closure.

for (var i = 0, row; row = table.rows[i]; i++) {
  (function(i) {
    console.log(row);
    console.log(completeData[i]);
    $(row).click(function(){
      window.location.hash = '#/dashboard/patients/' + completeData[i].patient_id;
    })
    // javascript for click, but there should be a ng-click way
    // $(row).attr('ng-click', 'changeView(/dashboard/patients/1)');
  })(i);
}

Because as it stands now, this line:

    $(row).click(function(){
      window.location.hash = '#/dashboard/patients/' + completeData[i].patient_id;
    })

will always refer i to the current value of i, not the value it had when the function was defined.


Alternatively, I recommend using jquery's $.each to clean up your loop and also build a closure at the same time:

$.each(table.rows, function(i, row) {
  console.log(row);
  console.log(completeData[i]);
  $(row).click(function(){
    window.location.hash = '#/dashboard/patients/' + completeData[i].patient_id;
  })
  // javascript for click, but there should be a ng-click way
  // $(row).attr('ng-click', 'changeView(/dashboard/patients/1)');
});
share|improve this answer
    
Thanks for including the link on top of your own explanation! –  Morgan May 20 '14 at 0:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.