How can I ensure an id remains defined after changes to the array?
I'm trying to create an app that can add, edit, and delete "facts" in a table, adapted from an example to-do list program. I use an id number to create a unique key for each td item, and attach it to a variable called todoItem
. This is all well and good. Adding and editing items works perfectly well.
However, when I try to delete an item (by splicing out a specific index in my array), todoItem
becomes undefined
. Something in the deletion function is also deleting the todoItem
variable. This means that after deleting an item, I can't add more items and get a TypeError: Cannot read property 'id' of undefined
error if I try to add one. There's no reference to todoItem
in my deletion function, so I don't understand how it's getting deleted.
const handleDelete = (id) => {
const deleteList = todos.map((oneTodo) => {
if (oneTodo.id === id) {
console.log("id "+id);
oneTodo = todos.splice(id, 1);
}
return oneTodo;
});
console.log(deleteList);
setTodos(deleteList);
console.log("todo, id:"+todo, id);
console.log("length: "+todos.length);
};
I am also getting an Warning: Each child in a list should have a unique "key" prop. Check the render method of FactsHandler.
error after running the deletion function (and not the add/edit functions). I suspect this is caused by the former problem, as I use the todoItem.id
to define a key for each item; if it's missing, a key can't be defined.
The code I'm writing is quite lengthy and a bit messy, so I'm adding the full code as pastebins. I'm thinking it could possibly be something else in my program, but I don't know where or what that would be. Any help would be appreciated. I've poured over this code for several hours this evening and haven't gotten anywhere.
FactsHandler (main function) https://pastebin.com/UzUpNyjK
Item (item component) https://pastebin.com/fncrRfDA
4 answers
-
answered 2021-01-11 05:20
Kalhan.Toress
try this out
const handleDelete = (id) => { const index = todos.indexOf(todo => todo.id === id); if (index !== -1) { todos.splice(index, 1); setTodos([...todos]); } };
-
answered 2021-01-11 05:20
Mohammad Faisal
javascript
array.map()
doesn't work the way you used it. you are supposed to return a new item for each element of the arrayYOu can use javascript
array.filter()
method for this purposeconst deleteList = todos.filter((oneTodo) => oneTodo.id !== id );
-
answered 2021-01-11 05:23
Alex Mckay
In my opinion you are using the wrong list operator (
map
) when you should be usingfilter
:const list = [ { id: "apple", label: "Apple" }, { id: "banana", label: "Banana" } ]; const deleteItem = (itemId) => list.filter(({ id }) => id !== itemId); deleteItem("apple") // => [{id: 'banana', label: 'Banana'}]
-
answered 2021-01-11 05:42
Parth Mansata
There are many ways to properly remove the object from the array. A reference of the same can be taken from here. Easiest ways, I found are:
- Using conditional for loop,
- Using Array.splice()
Ex.
let todos = [{ "id": 1, "name": "ABC" }, { "id": 2, "name": "DEF" }, { "id": 3, "name": "GHI" },]; const id = 1; // Approach 1 for(let i =0; i < todos.length; i++){ if(todos[i].id === id){ todos.splice(i, 1); break; } } // Approach 2 todos = todos.filter((oneTodo) => oneTodo.id !== id ); console.log('Updated todos:', todos);