Failed to execute removeChild on Node

Javascript

Javascript Problem Overview


Other stack answers such as this and this seem to be specialized cases and I believe my case is more generalized. I am doing this in my js:

var markerDiv = document.createElement("div");
markerDiv.innerHTML = "<div id='MyCoolDiv' style='color: #2b0808'>123</div>";
document.getElementById("playerContainer").appendChild(markerDiv);
		
// after a brief delay, REMOVE the appended child
setTimeout(function(){ 
	var myCoolDiv = document.getElementById("MyCoolDiv");
	document.getElementById("playerContainer").removeChild(myCoolDiv);
}, 1500);

Everything works correctly and as expected (the div is correctly appended and I can see it) until removeChild() is called, at which time I get the error Failed to execute 'removeChild' on 'Node'.

What am I doing wrong?

Javascript Solutions


Solution 1 - Javascript

Your myCoolDiv element isn't a child of the player container. It's a child of the div you created as a wrapper for it (markerDiv in the first part of the code). Which is why it fails, removeChild only removes children, not descendants.

You'd want to remove that wrapper div, or not add it at all.

Here's the "not adding it at all" option:

var markerDiv = document.createElement("div");
markerDiv.innerHTML = "<div id='MyCoolDiv' style='color: #2b0808'>123</div>";
document.getElementById("playerContainer").appendChild(markerDiv.firstChild);
// -------------------------------------------------------------^^^^^^^^^^^

setTimeout(function(){ 
    var myCoolDiv = document.getElementById("MyCoolDiv");
    document.getElementById("playerContainer").removeChild(myCoolDiv);
}, 1500);

<div id="playerContainer"></div>

Or without using the wrapper (although it's quite handy for parsing that HTML):

var myCoolDiv = document.createElement("div");
// Don't reall need this: myCoolDiv.id = "MyCoolDiv";
myCoolDiv.style.color = "#2b0808";
myCoolDiv.appendChild(
  document.createTextNode("123")
);
document.getElementById("playerContainer").appendChild(myCoolDiv);

setTimeout(function(){ 
    // No need for this, we already have it from the above:
    // var myCoolDiv = document.getElementById("MyCoolDiv");
    document.getElementById("playerContainer").removeChild(myCoolDiv);
}, 1500);

<div id="playerContainer"></div>

Solution 2 - Javascript

For me, a hint to wrap the troubled element in another HTML tag helped. However I also needed to add a key to that HTML tag. For example:

// Didn't work
<div>
     <TroubledComponent/>
</div>

// Worked
<div key='uniqueKey'>
     <TroubledComponent/>
</div>

Solution 3 - Javascript

The direct parent of your child is markerDiv, so you should call remove from markerDiv as so:

markerDiv.removeChild(myCoolDiv);

Alternatively, you may want to remove markerNode. Since that node was appended directly to videoContainer, it can be removed with:

document.getElementById("playerContainer").removeChild(markerDiv);

Now, the easiest general way to remove a node, if you are absolutely confident that you did insert it into the DOM, is this:

markerDiv.parentNode.removeChild(markerDiv);

This works for any node (just replace markerDiv with a different node), and finds the parent of the node directly in order to call remove from it. If you are unsure if you added it, double check if the parentNode is non-null before calling removeChild.

Solution 4 - Javascript

As others have mentioned, myCoolDiv is a child of markerDiv not playerContainer. If you want to remove myCoolDiv but keep markerDiv for some reason you can do the following

myCoolDiv.parentNode.removeChild(myCoolDiv);

JSFiddle

Solution 5 - Javascript

I was wraped it with <> as a parent when I changed it to normal , div , its worked fine

Solution 6 - Javascript

I'd a similar problem in the vue.js project. Then, I got a hint on changing the fragment wrapper to an HTML element. The most common use case for fragments is probably when you need to return multiple elements. With fragments this is easy and you don't need your typical wrapper div for the elements. Its short syntax is <></>.

Basically, I used the fragment pattern in Vue then I got the above error rendering the component dynamically using transition. It appears that the dynamic component(which entails multiple elements) needed to be wrapped with an HTML element, not a fragment.

// Vuejs
<transition
  name="router-anim"
  enter-active-class="animated animated-enter"
  mode="out-in"
  leave-active-class="animated animated-exit"
>
  <router-view /> // dynamic rendering based on current route using vue-router
</transition>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHerrimanCoderView Question on Stackoverflow
Solution 1 - JavascriptT.J. CrowderView Answer on Stackoverflow
Solution 2 - JavascriptdlchangView Answer on Stackoverflow
Solution 3 - JavascriptAnish GoyalView Answer on Stackoverflow
Solution 4 - JavascriptxortView Answer on Stackoverflow
Solution 5 - Javascriptahmed mersalView Answer on Stackoverflow
Solution 6 - JavascriptAkolade AdesanmiView Answer on Stackoverflow