Spot the bug - #136: Monster Incubator Lab

Why does my monster cloner refuse to copy child elements?

const incubator = document.querySelector("#incubator");
const lab = document.querySelector("#lab");
const cloneBtn = document.querySelector("#clone-btn");

function createMonsterCard(species, eyeballs, accessories) {
  const card = document.createElement("article");
  card.className = "monster-card";

  const title = document.createElement("h3");
  title.textContent = species;
  card.appendChild(title);

  const eyesWrap = document.createElement("div");
  eyesWrap.className = "eye-socket";
  for (let i = 0; i < eyeballs; i++) {
    const eye = document.createElement("span");
    eye.textContent = "👁️";
    eyesWrap.appendChild(eye);
  }
  card.appendChild(eyesWrap);

  const badge = document.createElement("span");
  badge.className = "badge";
  badge.textContent = `Gear: ${accessories.join(", ")}`;
  card.appendChild(badge);

  return card;
}

const prototypeMonster = createMonsterCard("Giggle Fiend", 3, ["Tiny Hat", "Spatula"]);
incubator.appendChild(prototypeMonster);

cloneBtn.addEventListener("click", () => {
  const source = incubator.firstElementChild;
  if (!source) return;

  const specimenClone = source.cloneNode(false);
  lab.appendChild(specimenClone);
});

Reply with what is broken and how you would fix it.

1 Like

The issue is cloneNode(false). It only clones the parent element not its children.

Fix it by using:

const specimenClone = source.cloneNode(true);

true = deep clone, so it copies all child elements too.

Also remove the extra svgsvg at the beginning if it is actually in your code.

oh, that’s a good guess! it’s true cloneNode(false) is the shallow clone. the answer will be posted later today.

It’s a tricky one. I’m leaning towards something with event listeners not being cloned properly.

That is clean

Oh cool

Been there

Lol yeah this happened to me too, I ended up just switching to a different data structure and never looked back.

Spot the Bug answer: The cloneNode method is called with false, which prevents cloning of child elements.

The fix:

Change source.cloneNode(false) to source.cloneNode(true).

Why:
The cloneNode method in JavaScript takes a boolean argument. When set to false, it only clones the node itself without any of its children. To include all descendants, the argument must be set to true for a deep clone.


Got it: @emmawalter5 :trophy:

First-answer leaderboard

  1. @Apexcodes - 6 (firsts) :trophy:
  2. @kirupa - 6 (firsts) :trophy:
  3. @emmawalter5 - 3 (firsts)
  4. @adnanahmed - 2 (firsts)