Home > Mobile >  Arrow function doesn't trigger inside a HTML
Arrow function doesn't trigger inside a HTML

Time:11-02

I've been working on a to do list for my web dev studies with The Odin Project. My assignment is to create a to-do app and I chose the composite design pattern to do after a lot of struggle with my previous messy code. So far so good but one of my button oddly doesn't trigger the arrow function I prepared for it. I said oddly cause I've got a very similar approach for another button the works perfectly. The only difference I feel it's causing this issue is an assignment to a button for the let's call it root of this tree structure (session.js class). document.getElementById effectively finds the specific button in the document and the addEventListener trigger a alert for example if there's no arrow function involved. Can anyone lend me a hand with this please?

The problem is in the addEventListener inside the if statement inside the addChild function of the following class

import Component from './component.js';

export default class Container extends Component{
  child;
  constructor(){
    super();
  }
  addChild(id, parentId){
    alert(id);
    alert(parentId);
    document.getElementById(parentId).appendChild(document.createElement('div')); 
    document.getElementById(parentId).lastChild.id = id;
    document.getElementById(parentId).lastChild.innerHTML = this.child.innerHTML;
    document.getElementById(parentId).lastChild.className = this.child.className;

    if(document.getElementById(id).className!='check-list'){
      document.getElementById(id).innerHTML ="<button id='" id "-add-button'></button>";
      document.getElementById(id '-add-button').addEventListener('click', ()=>{
       this.child.addChild(this.parentNode.id);
      });
    }

    document.getElementById(id).innerHTML ="<button id='" id "-remove-button'></button>";

    document.getElementById(id '-remove-button').addEventListener('click', ()=>{
    document.getElementById(id).parentNode.removeChild(document.getElementById(id)); 
    });    

    let inputs = document.getElementById(parentId).getElementsByClassName('input');
    for(let i=0; i<inputs.length;   i){ 
     inputs[i].addEventListener('input', ()=>{
       inputs[i].dataset.storage = inputs[i].value;});
    }
  }
}

Container class inherits from Component class

export default class Component{
    className;
    innerHTML; 
  constructor(){
  }
}

And Session class is the only class that, if I can call it override in this case the same event

import Project from "./project.js";
import Container from "./container.js";

export default class Session extends Container{
  constructor(username){
    super();
    this.username = username;
    this.child = new Project();
    this.innerHTML = ["<div id='" this.username "-session' class='session' data-checklist='' data-card='' data-list='' data-project''>",
                "<H1>Call it a day!</H1>",
                "<button id='session-add-button'>Add Project</button>",
                "<button id='logout'>Log out</button>",
                "</div>"].join("");  
    document.body.innerHTML = this.innerHTML;
    document.getElementById('session-add-button').addEventListener('click', ()=>{
      this.addChild(this.username "-session");
    })
  }

  addChild(parentId){
    super.addChild(Project.getId(), parentId);
      Project.count;
  }
}

BTW Project class is Session class child so you guys can picture the whole flow in your minds

import Container from "./container";
import List from "./list";

export default class Project extends Container {
  static count=0;
  static getId(){
    return 'P-' Project.count;
  }
  constructor(){
    super();
    this.child = new List();
    this.className = 'project';
    this.innerHTML = ["<input class='input' data-storage='' type='text' placeholder='Project title'></input>"].join("");
  }

  addChild(parentId){
    super.addChild(List.getId(), parentId);
      List.count;
  }
}

I've checked already if the button inside that if in the container.js script is found as well as declare a function without the arrow function. I've also tried to find the difference between this add button that has issues with the remove button and I can't see anything that I'm doing wrong in terms of typing or syntax.

CodePudding user response:

You could use something like addEventListener('click', (event) => {}); and then inside that reference the event properties like target re: https://developer.mozilla.org/en-US/docs/Web/API/Event/target

Super simple example: where now you DO have this as well

// Make a list
const ul = document.createElement('ul');
document.body.appendChild(ul);

const li1 = document.createElement('li');
const li2 = document.createElement('li');
const btn = document.createElement('button');
btn.textContent = "Howdy Click me, I am not the li here but the UL triggers";
li2.appendChild(btn);
ul.appendChild(li1);
ul.appendChild(li2);

function hitMe(event) {
  // event.target refers to the clicked <li> element
  // This is different than event.currentTarget, which would refer to the parent <ul> in this context
  event.target.classList.toggle('blue-sky');
  event.currentTarget.classList.toggle("red-sky");
  console.log(this);
    console.log("target?:",this == event.target);
  console.log("currentTarget:?",this == event.currentTarget);
}

// Attach the listener to the list
// It will fire when each <li> is clicked
ul.addEventListener('click', hitMe, false);
ul {
  border: solid 1px green;
}

li {
  border: solid 3px orange;
}

.blue-sky {
  border-color: skyblue;
}

.red-sky {
  background-color: #ffdddd;
  border-width: 4px;
  padding: 1em;
}

CodePudding user response:

Arrow functions don't have their own bindings to this as methods, so this in your function refers to the window

  document.getElementById('session-add-button').addEventListener('click', ()=>{
      this.addChild(this.username "-session"); // `this` refers to `Window`
    })

To fix just use an anonymous function, e.g.

  var username = this.username;
  document.getElementById('session-add-button').addEventListener('click', function() {
      this.addChild(username "-session"); // `this` refers to your button
    })

Your other use of the arrow function works because you don't reference this in it.

  • Related