skip to Main Content

I have a student arry
const students = []

and i have addEventListener

form.addEventListener("submit", function (event) {

  event.preventDefault();

  const student = {
    name: this.name.value,
  };

  students.push(student);

   this.reset();

  renderStudents();
});

I have this render students function that i called in the addEventListener

function renderStudents() {

  students.forEach((student) => {

    const tr = document.createElement("tr");

    const tdName = document.createElement("td");
    tdname.innerText = student.name;

    tr.append(
      tdName,
    );

    table.appendChild(tr);
  });

When i add one student it will display in the table, but when i try to add another student, the previous students gets also added to the table again.

I could solve that by adding table.innerHTML = "" to the renderStudents() function at the start, is there any other way to solve that?
Because it feels like this would give other errors

4

Answers


  1. Chosen as BEST ANSWER

    Okay so there a actually serveral ways to solve this, and using while() is one of them.

    Now what you could do is simply add a while lopp in the renderStudents() function, but NOTE that you will have to add it at the start, like this:

       function renderStudents() {
    
        while(table.firstChild){ 
            table.removeChild(table.firstChild) // this will remove the firstChild of the element
        }
    
      students.forEach((student) => {
    
        const tr = document.createElement("tr");
    
        const tdName = document.createElement("td");
        tdName.innerText = student.name;
    
        tr.append(
          tdName
        );
    
        table.appendChild(tr);
      });
    }
    

    What this will do is that it will remove the first child everytime we call the renderStudent() function.


  2. I think you issue is with the students Array.

    You should avoid to use this global variable and just pass the Array to the renderStudents() function.

    So like this:

    form.addEventListener("submit", function (event) {
    
      event.preventDefault();
    
      const student = {
        name: this.name.value,
      };
    
      this.reset();
    
      renderStudents([ student ]); // Pass the Array to the function
    });
    
    
    function renderStudents(students) {
    
      students.forEach((student) => {
    
        const tr = document.createElement("tr");
    
        const tdName = document.createElement("td");
        tdname.innerText = student.name;
    
        tr.append(
          tdName,
        );
    
        table.appendChild(tr);
      });
    
    

    You can other stratiegies and use the global students Array to have your model with all the students inside, and just check on your code there are not duplication on the list.

    Then you create all the rows on each add, after you removed all the existing one from the DOM.

    Or you can to filter the students Array getting only the students that need to be added checking what already present.

    This will be a problem when your table will get a lot of records.

    Login or Signup to reply.
  3. You just need to add what you are setting, there is no reason to loop over the array. Change your code to use what you need to add.

    const table = document.querySelector("#t tbody");
    
    function renderStudents(additionalStudents) {
    
      additionalStudents.forEach((student) => {
    
        const tr = document.createElement("tr");
    
        const tdName = document.createElement("td");
        tdName.innerText = student.name;
    
        tr.append(tdName);
    
        table.appendChild(tr);
      });
    }
    
    var students = [{
      name: 'a'
    }];
    renderStudents(students);
    
    var newStudent = {
      name: 'b'
    };
    students.push(newStudent);
    renderStudents([newStudent]);
    <table id="t">
      <tbody>
      </tbody>
    </table>

    So your code would be

    form.addEventListener("submit", function (event) {
    
      event.preventDefault();
    
      const student = {
        name: this.name.value,
      };
    
      students.push(student);
    
       this.reset();
    
      renderStudents([student]);
    });
    
    function renderStudents(additionalStudents) {
    
      additionalStudents.forEach((student) => {
    
        const tr = document.createElement("tr");
    
        const tdName = document.createElement("td");
        tdname.innerText = student.name;
    
        tr.append(
          tdName,
        );
    
        table.appendChild(tr);
      });
    
    Login or Signup to reply.
  4. You can use another array (const studentsRendered = []) to track the already rendered elements. Then in your event handler check if (!studentsRendered.includes(student)) and render the student and add it to studentsRendered. This way only the newly added student will be added to the table.
    Here is an example with pre-loaded data in the students array:

    const form = document.querySelector('#form')
    const table = document.querySelector('#table')
    const studentsRendered = []
    const students = [{
      name: 'pre-loaded name'
    }]
    
    form.addEventListener("submit", function(event) {
      event.preventDefault();
      const student = {
        name: this.name.value,
      };
      students.push(student);
      this.reset();
      renderStudents();
    });
    
    function renderStudents() {
      students.forEach((student) => {
        if (!studentsRendered.includes(student)) {
          const tr = document.createElement("tr");
          const tdName = document.createElement("td");
          tdName.innerText = student.name;
          tr.append(
            tdName,
          );
          table.appendChild(tr);
          studentsRendered.push(student)
        }
      });
      console.log(studentsRendered)
    }
    renderStudents()
    <form id="form">
      <label for="name">Student Name</label>
      <input type="text" name="name">
      <button>
        add
      </button>
    </form>
    <table id="table">
      <tr>
        <th>Name</th>
      </tr>
    </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search