'How to add and delete customers to html using JS?

Implement the showCustomers function so that it renders customers as list items. The first argument to the function, customers, is an array of objects with the name and email properties. The second argument to the function, targetList, is an unordered HTML list to which each customer should be added as a separate list item.

The name and email properties should be added as two paragraphs inside the list item. The email HTML element should not be present at first, and its HTML element should be added / removed when the name is clicked.

I managed to add the list but the remove function is not working. if anyone can help.

let customers = [{
    name: "John",
    email: "[email protected]"
  },
  {
    name: "Mary",
    email: "[email protected]"
  }
];

function addItem() {
  var ul = document.getElementById('customer');

  for (var i = 0; i < customers.length; i++) {
    var li = document.createElement('li');
    var paraName = document.createElement("p");
    var nameNode = document.createTextNode(customers[i]['name']);
    paraName.appendChild(nameNode);

    var paraEmail = document.createElement('p');
    var emailNode = document.createTextNode(customers[i]['email']);
    paraEmail.appendChild(emailNode);
    li.appendChild(paraName);
    li.appendChild(paraEmail);
    ul.appendChild(li);
  }
}

addItem();

function removeItem() {
  nameNode.addEventListener('click', li.removeChild(nameNode));
}
removeItem();
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://stacksnippets.net/js"></script>
</head>
<body>
  <ul id='customer'>
  </ul>
  <script>
  </script>
</body>
</html>


Solution 1:[1]

You've declared nameNode in addItem function. Thus it can't be accessed from removeItem check out JavaScript variable scopes

And your logic to remove element is also wrong. you're directly using li, not the element on which the click event has happened. And also, the click event is of no use as you're applying it on nameNode. Because it is string and not a node. log it to see the content. you need to apply the event on the element and not the content. so you will need to apply the event on paraName.

As you can't access variables you used in the for loop, you will need to bind event listeners from inside of the for loop. And you'll have to check on which element the event happened, (e.target) and from it's parent element (li) remove the second child which is email.

let customers = [{
    name: "John",
    email: "[email protected]"
},
{
    name: "Mary",
    email: "[email protected]"
}
];

function addItem() {
    var ul = document.getElementById('customer');

    for (var i = 0; i < customers.length; i++) {
        var li = document.createElement('li');
        var paraName = document.createElement("p");
        var nameNode = document.createTextNode(customers[i]['name']);
        paraName.appendChild(nameNode);

        var paraEmail = document.createElement('p');
        var emailNode = document.createTextNode(customers[i]['email']);
        paraEmail.appendChild(emailNode);
        li.appendChild(paraName);
        li.appendChild(paraEmail);
        ul.appendChild(li);

        paraName.addEventListener("click", (e) => {
            let x = e.target.parentElement;
           x.removeChild(x.childNodes[1]);
        })
    }
} 
addItem();
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://stacksnippets.net/js"></script>
</head>
<body>
  <ul id='customer'>
  </ul>
  <script>
  </script>
</body>
</html>

I'll leave on click add email functionality to you to figure out.

Solution 2:[2]

for(let j = 0; j < lis.length; j++) {
    var p = lis[j].getElementsByTagName('p');
    let count = 0;
    p[0].addEventListener('click', (e) => {
        var paraEmail = document.createElement('p');
        var emailNode = document.createTextNode(customers[j]['email']);
        paraEmail.appendChild(emailNode);
        let x = e.target.parentElement;
        if(count == 0) {
            x.appendChild(paraEmail);
            count = 1;
        } else if(count == 1) {
            e.target.nextElementSibling.remove();
            count = 0;
        }
    });
}

Solution 3:[3]

  //This will give you 100% perfect result
  
  function showCustomers(customers, targetList){
     for(var customer in customers){
      let li = document.createElement('li');
      let p = document.createElement('p');
      li.appendChild(p);
     let name = document.createTextNode(customers[customer].name);
     p.appendChild(name);
     targetList.appendChild(li);
    }
    var first_P_elements =[...document.getElementsByTagName('li')];
     first_P_elements.forEach(function(el,i){
      el.children[0].addEventListener('click',function(){
       if(el.children.length>1){
         el.children[1].remove();
       }else 
       {
      let p2 = document.createElement('p');
      let email = document.createTextNode(customers[i].email);  
      p2.appendChild(email);
     this.parentElement.appendChild(p2);
           }
       });
    });
     }
    document.body.innerHTML = `<div><ul id="customers"></ul></div>`;
    let customers = [{name: "John", email: "[email protected]"},
                     {name: "Mary", email: "[email protected]"}];
    showCustomers(customers, document.getElementById("customers"));
    let customerParagraph = document.querySelectorAll("li > p")[0];
    if(customerParagraph) {
      customerParagraph.click();
    }
    console.log(document.body.innerHTML);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Aniket Kariya
Solution 2 AbsoluteBeginner
Solution 3