Sackadelic
Sackadelic

Reputation: 1019

How to use template literals in a constructor in JavaScript

I'm building a To Do list app and have a question regarding OOP and JavaScript. I want to create a value in the Constructor that holds my taskBody which contains the HTML and template literal that will be assigned by either the input value or an eventual population from local storage. My goal is to re-use this HTML in two separate functions, but I'm stuck with the template literal.

class Task {
  constructor() {
    let taskValue //Initializing a variable

    this.taskBody = `<div class="task">
    <span>${taskValue}</span> //Template Literal
      <span class="actions">
       
        <a class="edit-button" title="Edit Task">Edit</a>
        <button class="complete-button" title="Complete Task"><i class="fas fa-check"></i></button>
        
      </span>
    </div>`;

  }

  addTask = () => {
    //Prevent empty task
    if (this.input.value == "") {
      this.setPlaceholder("Please Enter A Task");
      return;
    }

    this.taskValue = this.input.value; //Trying to reassign taskValue to the input value

    this.results.innerHTML += this.taskBody; //Trying to grab the HTML from the constructor and populate with taskValue able

    ls.setLS(this.taskValue); //setting the Local Storage the Task Value, which works
  };

}

I expect if I type "Stack Overflow" in the to-do list, "Stack Overflow" populates in the HTML and the Local Storage, however, it only populates in the Local Storage. The todo item is either undefined, null, or empty.

I've tried using this.taskValue, let taskValue = "", and let taskValue = null, but I get the results described above. Where am I going wrong, and more specifically, how can I reuse the HTML in different functions?

Here's a CodePen where you can see the issue:

Codepen

Upvotes: 1

Views: 315

Answers (1)

Aziza Kasenova
Aziza Kasenova

Reputation: 1571

When you first instantiate the Task, the value of the this.taskBody is set as below:

<div class="task">
    <span>undefined</span>
    <span class="actions">
       
        <a class="edit-button" title="Edit Task">Edit</a>
        <button class="complete-button" title="Complete Task"><i class="fas fa-check"></i></button>
        
    </span>
</div>

with undefined value, because at the moment of instantiation, the taskValue is undefined.

If your todo list items are added dynamically (which is the case), consider having a function which will enable dynamic replacement, like:

getTaskBody = item => `<div class="task">
    <span>${item}</span>
    <span class="actions">
       
        <a class="edit-button" title="Edit Task">Edit</a>
        <button class="complete-button" title="Complete Task"><i class="fas fa-check"></i></button>
        
    </span>
</div>`;

and use it later in line 123, instead of:

this.results.innerHTML += this.taskBody;

do:

this.results.innerHTML += getTaskBody(this.taskValue);

Upvotes: 2

Related Questions