Cannot read property `parentNode` of undefined

The worm picture The worm · Oct 31, 2016 · Viewed 10.2k times · Source

I have a function that creates a HTML table:

makeHTMLTable: function(array){
    var table = document.createElement('table');
      for (var i = 0; i < array.length; i++) {
        var row = document.createElement('tr');
        var cell = document.createElement('td');
        cell.textContent = array[i];
        row.appendChild(cell);
        cell = document.createElement('td');
        var msgButton = document.createElement('button');
        msgButton.setAttribute("id", "msgButton" +i);
        msgButton.textContent = "message";
        msgButton.addEventListener("click", this.messageUser, false);
        cell.appendChild(msgButton)
        row.appendChild(cell);
        table.appendChild(row);
      }
      return table;
  },

I then have this function:

messageUser: function(){
    debugger;
    this.parentNode.parentNode.remove();
    unMatch();
  },

When I click the msgbutton I am expecting it to remove the whole row including the button itself and the little bit of text that comes back. i.e:

hello [msgbutton]

goodbye [msgbutton]

If i click [msgbutton] on the hello row it will look like this:

goodbye [msgbutton]

but so far this: this.parentNode.parentNode.remove(); is returning undefined..

EDIT:

I call this.retrieveMatches() in an earlier promise this.fetchMatches() returns an array

  retrieveMatches: function(){
    var tableResult = this.makeHTMLMatchesTable(this.fetchMatches(object));
    var matches = document.getElementById('matches')
    matches.parentNode.insertBefore(tableResult, matches);
  },

Answer

Thum Choon Tat picture Thum Choon Tat · Oct 31, 2016

You're trying to call the object that holds "messageUser" function, not the HTML element. For example:

var obj = {
    notify: function(msg){
        alert(msg);
    },
    messageUser: function(){
        this.notify("some message"); //This line will call obj.notify()
        this.parentNode.parentNode.remove(); //obj is not a HTML element, therefore it will create an error
    }
}

Since you're adding event listeners in a loop, you need to create a function that binds an event listener.

function bindEvent(button){
    button.addEventListener("click", function(){
        this.parentNode.parentNode.remove(); //"this" refer to the "button" object
    }, false);
}

You can place the function above before returning the object "table"