I'm puzzled by the "Uncaught TypeError:" error message and can't seem to figure it out

I'm having trouble displaying the value of 'true' within my objects and keep encountering an error message.

Uncaught TypeError: Cannot set property 'toDoIsRemoved' of undefined  
  at removeTask (main.js:85)  
  at HTMLButtonElement.<anonymous> (main.js:56)

The error message points to an issue with line 56:

deleteButton.addEventListener('click', ()=>{removeTask(allTheToDos[i])});

Here is the entire 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 am looking to be able to click on any button associated with my todos to change the value from false to true.

Answer №1

The issue arises when i is not defined using let. This causes the use of the global variable i, resulting in i being set to allTheToDos.length after iterating. Consequently, when the event handler is clicked, it uses this index, which is undefined.

Summarizing the problem:

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 within the loop, but triggered by a button click, occurring after the loop wraps up and i no longer satisfies i < letters.length
    console.log(i, letters[i]);
  });
  document.body.append(button);
}

The solution lies in defining i with let (avoid using var to prevent the same issue). Using let ensures that i is scoped to the block, where each iteration has a distinct i variable that only changes within the same block.

const letters = ["a", "b", "c"];

// Define i using let to scope it to the for-loop
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);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble accessing the root route in production environment

After creating a basic Node application with 5 routes that serve different HTML documents, I encountered an issue. While all the routes function properly when running on localhost, in production my root route displays a 404 error page, indicating that the ...

Setting attributes on an AngularJS Directive element in real time

My goal is to create a directive in AngularJS with a template that can contain other AngularJS directives. All of my directives require an "id" attribute, so I must set the "id" on the directive within the template. However, no matter how I attempt this, A ...

Is it possible to obtain the parameters using an empty object with the getStaticPaths function?

Within the getStaticPaths function, a path is returned with params postId:1. If additional params like postId: 2 or postId: 3 are included, they will also be statically generated. Is my understanding correct? Is there a way to avoid loading any post based ...

The jQuery selector is unable to locate the IMG element using its unique ID

I'm experiencing an issue with a webpage that includes the following code snippet: <img class="img-qrcode" id="img_123.000.00.01" src="http://localhost:7777/data/code_img\123.000.00.01.png" alt="./data/code_img\123.000.00.01. ...

What is the functioning of the node.js next() middleware without any parameters supplied?

When working with middleware functions in Express, the signature typically includes function (req, res, next). However, it may be surprising to some that the next() call does not require any arguments. This concept can be better understood by considering t ...

SSL-enabled Websocket server powered by websocket.io

I have built a basic Websocket server using node.js and websocket.io var ws = require('websocket.io') , server = ws.listen(8000); server.on('connection', function (socket) { console.log("connected"); socket.on('message&ap ...

What steps do I need to follow to utilize LiveReload with an AngularJS templateURL?

Is there a way to trigger the reload of templateURL when using LiveReload and Grunt? angular.module('meshApp', [ 'ngSanitize', 'ngRoute' ]) .config(function ($routeProvider) { $routeProvider .when('/&apos ...

Having trouble exporting an object from a different JavaScript file in Node.js

I have been attempting to make the getCurrentSongData function retrieve the songdata object passed in from the scraper. However, I am encountering the following output: ******************TESTING**************** c:\Users\(PATH TO PROJECT FOLDER)& ...

The POST function isn't functioning correctly within the temp.js file

My issue with the post method: var newUser = { "user5" : { "name" : "john", "password" : "qwerty123", "profession" : "developer", "id": 5 } } app.post('/createUser', function (req, res) { // Reading existing use ...

Choose from the select2 multiselect options and lock certain selected choices from being altered

I have coded a select dropdown with preselected options, some of which I want to keep fixed so that users cannot change them. To achieve this, I implemented the following code: <select id="select2-multiple" name="users" multiple="multiple" style="width ...

Leveraging dynamic anchor tags within a Chrome extension

In my current project, I am dynamically generating anchor tags and using them to redirect to another page based on their unique IDs. While I have successfully implemented this feature using inline scripts in the past, I ran into an issue with Chrome exte ...

Can Vue allow for the inclusion of HTML elements to store data seamlessly?

One example involves displaying array elements in an <ul>, with each element starting with <li> and ending with </li>. Here is the attempted code: clearedtaskslist: function(){ this.template='<ul>' for(let i=0;i<t ...

Uploading and saving data to an object in FaunaDB using React hook forms

I am currently facing an issue with uploading/saving data to an object in FaunaDB. Specifically, I am trying to upload a string to a jobProfile object: data: { "jobProfile": { "image": "" "coverImage": " ...

How can the input validation be displayed in Ajax when the user interacts with it?

When utilizing Ajax, I only want to display validation for the input field that the user is interacting with, not all validations at once. Currently, my script shows all validations simultaneously when any input is filled out. How can I modify my code so t ...

Convert JavaScript object into distinct identifier

I have a data object where I'm storing various page settings, structured like this: var filters={ "brands":["brand1","brand2","brand3"], "family":"reds", "palettes":["palette1","palette2","palette3"], "color":"a1b2" }; This object is ...

Loading scripts dynamically with async/await in JavaScript

I may be committing a typical beginner error. Aim I have a script named loader.js, where I intend to provide a collection of JavaScript files that control the shape, size, and position of components. The structure of the file is as follows: const loadSc ...

Passing a class as a parameter in Typescript functions

When working with Angular 2 testing utilities, I usually follow this process: fixture = TestBed.createComponent(EditableValueComponent); The EditableValueComponent is just a standard component class that I use. I am curious about the inner workings: st ...

Challenges with loading times in extensive AngularJS applications

We are currently tackling performance issues related to the loading time of our AngularJS application. The page takes a significant amount of time to load, and we are exploring potential causes for this delay. One factor that could be contributing to the ...

Is your URL getting cut off in jQuery?

How can I properly display a URL in an HTML table without it getting truncated? I'm attempting to show it within a table using jQuery, but it seems to be cutting off the URL. Here's a snippet of my code. Any suggestions on how to fix this? <! ...

What could be causing the failure of the update for this computed property in my Vue 3 application?

Currently, I am in the process of creating an audio player using Vue 3 and the Napster API. About the Project I have managed to make the vinyl rotate by utilizing a CSS keyframes-based animation paired with the computed property isSpinning. I intend for ...