Reputation: 89
I'm trying to print out a value off true within my objects but for some reason i keep getting this error message.
Uncaught TypeError: Cannot set property 'toDoIsRemoved' of undefined
at removeTask (main.js:85)
at HTMLButtonElement.<anonymous> (main.js:56)
It says that there is something wrong with line 56:
deleteButton.addEventListener('click', ()=>{removeTask(allTheToDos[i])});
here is that whole function:
function generateHtml (){
// Creating an Ul for my items
let section = document.getElementById('mySection');
let myUl = document.createElement('ul');
myUl.className = 'listContainer';
section.appendChild(myUl);
// Creating the loop for my premade todo objects
for(i=0; i<allTheToDos.length; i++){
// Create a div wrapper for my li
let myListWrapperItemContainer = document.createElement('div');
myListWrapperItemContainer.className = 'listItemsWrapper';
// Creating Checked button
let checkedIcon = document.createElement('label');
checkedIcon.className = 'checkedIcon listItemsIcon';
checkedIcon.innerHTML = '<i class="fas fa-check"></i>';
//Creating li
let myLi = document.createElement('li');
myLi.classList = 'listItem lineTrough';
myLi.id= 'listItem';
// Creating delete button
let deleteButton = document.createElement('button');
deleteButton.id ='deleteButton';
deleteButton.className = 'trashCan listItemsIcon';
deleteButton.innerHTML = '<i class="fas fa-trash-alt"></i>';
// OnClick
deleteButton.addEventListener('click', ()=>{removeTask(allTheToDos[i])});
// Adding everything to my html
myListWrapperItemContainer.appendChild(checkedIcon);
myListWrapperItemContainer.appendChild(myLi);
myListWrapperItemContainer.appendChild(deleteButton);
myLi.innerHTML = allTheToDos[i].toDoItem;
myUl.appendChild(myListWrapperItemContainer);
}
}
and:
function removeTask (done){
done.toDoIsRemoved = true;
console.log(allTheToDos);
}
i want to be able to click on any button off my todos and be able to change the value from false to true.
Upvotes: -1
Views: 251
Reputation: 21120
The problem is that you don't define i
using let
. Meaning you are using the global variable i
. i
will be allTheToDos.length
after iterating. When you then later click on the event handler it will use this index, of which the value is undefined
.
Here is the problem in short:
const letters = ["a", "b", "c"];
// GLOBAL i
for (i = 0; i < letters.length; i++) {
const button = document.createElement("button");
button.append(letters[i]);
button.setAttribute("type", "button");
button.addEventListener("click", () => {
// The line below is not called within the loop, but when
// you click the button. This happens after the loop is
// finished, which is when i no longer matches
// i < letters.length
console.log(i, letters[i]);
});
document.body.append(button);
}
The solution is to define i
using let
(don't use var
or you will have the same problem). Using let
will scope i
to the block, so each for-iteration has its own i
variable, which only changes if you change it within the same block.
const letters = ["a", "b", "c"];
// define i using let, scoping it to the for-block
for (let i = 0; i < letters.length; i++) {
const button = document.createElement("button");
button.append(letters[i]);
button.setAttribute("type", "button");
button.addEventListener("click", () => {
console.log(i, letters[i]);
});
document.body.append(button);
}
Upvotes: 1