0

I created a function for reusing the splice feature for javascript arrays however, after I run it once, it cannot be reused.

var removePerson = function(d, person_id) { 
  var person_index = d.findIndex(i => i.id == person_id);
  d.splice(person_index, 1);
  return d;
};

I am not getting console errors. I do not know how to debug it. Here is my JSFiddle.

If you run the example, you will see you can remove any 1 person from the list, but when you try to remove either of the remaining 2, nothing happens (e.g. console errors, console response). Any idea how I can support reuse for my removePerson() function?

1
  • 2
    once you repopulate using populateList, all the event handlers attached using $(".delete").on("click" are gone - you'll want to look into Event Delegation - or you can re-attach the event handlers after every call to populateList Commented Nov 30, 2017 at 2:56

2 Answers 2

3

Your solution doesn't work because of how your populateList works.

In your populateList, you have a line:

$('#load').empty();

This line empties the table and removes the buttons attached with click event listener.

Then, you add completely new button.delete, which aren't attached with any event listener.

To solve this, you can put your .on() into populateList function.

var populateList = function(d) {
    $("#load").empty();
    var new_rows;
    for(var i = 0; i < d.length; i++) {
        new_rows += "<tr>" + 
            "<td>" + d[i].id + "</td>" +
            "<td>" + d[i].name + "</td>" +
            "<td>" + d[i].phone + "</td>" +
            "<td><button class='delete' data-id='" + d[i].id + "'>delete</button></td>" +
            "</tr>";
    }
    $("#load").append(new_rows);

    // delete event
    $(".delete").on("click", function() {
      var delete_sel = $(this).attr("data-id");
      populateList(removePerson(d, delete_sel));
    });
};

Here's a working jsFiddle.

Alternatively, you can use solution from this answer (which is a cleaner solution imo).

$("table").on("click",".delete", function() {
  var delete_sel = $(this).attr("data-id");
  populateList(removePerson(data, delete_sel));
});

More explanation on why his answer works on jQuery documentation (Look at the selector parameter).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for explaining what was going on. Your solution works as well as @TC Lynks. Between the 2 of them, which would you say is more elaborate? Would you say your's is, because it regards Event Delegation, as mentioned by Jaromanda X?
I would prefer the implementation by @TCLynks because it makes use of the event delegation and logically, his solution will have better performance because the script doesn't need to repeatedly add event listener. My solution is for the sake of easy understanding.
2

Try this code:JSFiddle

or the code snippet:

var removePerson = function(d, person_id) {	
	var person_index = d.findIndex(i => i.id == person_id);
	d.splice(person_index, 1);
  return d;
};

var populateList = function(d) {
	$("#load").empty();
	var new_rows;
	for(var i = 0; i < d.length; i++) {
		new_rows += "<tr>" + 
			"<td>" + d[i].id + "</td>" +
			"<td>" + d[i].name + "</td>" +
			"<td>" + d[i].phone + "</td>" +
			"<td><button class='delete' data-id='" + d[i].id + "'>delete</button></td>" +
			"</tr>";
	}
	$("#load").append(new_rows);
};


$(document).ready( function() {

		// initial list
    var data = [
    	{
        "id": 1001,
        "name": "Andy Roy",
        "phone": "555-555-5551"
      },
      {
        "id": 1002,
        "name": "Bob Dillon",
        "phone": "555-555-5552"
      },
      {
        "id": 1003,
        "name": "Carl Sagan",
        "phone": "555-555-5553"
      }
    ];
		
    //initial populate list
    populateList(data);
    
    // delete event
    $("table").on("click",".delete", function() {
      var delete_sel = $(this).attr("data-id");
      populateList(removePerson(data, delete_sel));
    });
    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border>
<thead>
<tr><th>ID</th><th>Name</th><th>Phone</th></tr>
</thead>
<tbody id="load"></tbody>
</table>


 $("table").on("click",".delete", function() {
  var delete_sel = $(this).attr("data-id");
  populateList(removePerson(data, delete_sel));
});

1 Comment

looks to be a solution. So it was a DOM selection issue? Is this related to cached memory?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.