Home > Mobile >  How not to add duplicate elements in the DOM
How not to add duplicate elements in the DOM

Time:12-24

I know it is a very easy question but I am still struggling. I created a function which adds element in an Array and after that I am using forEach loop for appending them in the DOM. But I am unable to prevent addition of duplicate elements.

const btn = document.querySelector("button");

btn.addEventListener("click", () => {
  addItem(btn.innerText);
});

function addItem(item) {
  let items = [];

  if (!items.includes(item)) {
    items.push(item);
  }

  items.forEach((element) => {
    const li = Object.assign(document.createElement("li"), {
      innerText: element
    });

    document.body.appendChild(li);
  });
}
@import url("https://cdn.jsdelivr.net/gh/KunalTanwar/organise.css/css/organise.inter.min.css");
body {
  display: grid;
  place-items: center;
}

button {
  border: 0;
  background: none;
  padding: 1rem 2rem;
  box-shadow: inset 0 0 0 1px gray;
}
<button> Add Me </button>

What I have tried so far :

[...new Set(items)].forEach((element) => {
  const li = Object.assign(document.createElement("li"), {
    innerText: element
  });

  document.body.appendChild(li);
});

Another Method -

if (!items.includes(item)) {
  items.push(item);
} else {
  return
}

lastly -

if (!items.includes(item)) {
  items.push(item);
} else {
  items = [...new Set(items)]
}

But still no luck!!

CodePudding user response:

items needs to be declared outside of the function so it has a global scope, currently, you are declaring it to an empty array on each call to the function in the scope of the function, so it can't find any existing items, also you need to return from your function if the value is found in the array, as pointed out in a friendly comment, I also was not accounting for multiple buttons, which I added a fix for this to add event listeners to all buttons.

const btns = document.querySelectorAll("button");
let items = [];
btns.forEach(b => b.addEventListener("click", () => {
     addItem(b.innerText);
}));

function addItem(item) {
  if (!items.includes(item)) {
     items.push(item);
  } else {
     return;
  }

  
  const li = Object.assign(document.createElement("li"), {
     innerText: item
  });

  document.body.appendChild(li);
  
}
@import url("https://cdn.jsdelivr.net/gh/KunalTanwar/organise.css/css/organise.inter.min.css");
body {
  display: grid;
  place-items: center;
}

button {
  border: 0;
  background: none;
  padding: 1rem 2rem;
  box-shadow: inset 0 0 0 1px gray;
}
<button>Add Me</button>
<button>Add Me Again</button>

CodePudding user response:

First you redefine items every time so you are resetting it so you are checking against an empty array.

Once you fix that you are looping over the array every time so you will keep adding elements. You only want to append the element you are adding.

// Better demo, multiple buttons
const btns = document.querySelectorAll("button");
btns.forEach(btn => {
  btn.addEventListener("click", () => {
    addItem(btn.innerText);
  });
});

// broke out the render code so we an call it in other places
// smaller chunks makes it easier to reuse
function renderItem(innerText) {
  const li = Object.assign(document.createElement("li"), {
    innerText
  });
  document.querySelector("#out").appendChild(li);
}

// define this outside the method so it holds it
// Added some default values just for fun
const items = ["d1", "d2"];

// If you want to have default things or pull from localstorage
// you can render the items in the array
items.forEach(renderItem);

// triggered by the click, add the items to UI
function addItem(item) {
  // have we seen it? Yes exit
  if (items.includes(item)) return;

  // add the item
  items.push(item);

  // show it
  renderItem(item);
}
@import url("https://cdn.jsdelivr.net/gh/KunalTanwar/organise.css/css/organise.inter.min.css");
body {
  display: grid;
  place-items: center;
}

button {
  border: 0;
  background: none;
  padding: 1rem 2rem;
  box-shadow: inset 0 0 0 1px gray;
}
<button type="button"> Add Me 1</button>
<button type="button"> Add Me 2</button>
<button type="button"> Add Me 3</button>

<ul id="out"></ul>

  • Related