The way I’m implementing is when i click the star-icon, it’ll turn solid and will be added to Favorites and it’ll be removed from Favorites when the star-icon is clicked again.
This is the error I get:
Failed to execute ‘removeChild’ on ‘Node’: The node to be removed is not a child of this node. at remove From Favorites.
document.addEventListener("DOMContentLoaded", function() {
const openStudyResource = document.getElementById("openStudyResource")
const favorites = document.getElementById("favorites")
const studyResourceContainer = document.getElementById("studyResourceContainer")
const jsonBoxes = document.getElementById("resources")
const selectedResource = new Set();
openStudyResource.addEventListener("click", function(){
studyResourceContainer.style.left = "60px";
})
function addToFavorites(resource){
const clone = resource.cloneNode(true);
favorites.appendChild(clone);
}
function removeFromFavorites(resource){
favorites.removeChild(resource);
}
function toggleFavorites(starIcon, resource){
console.log(favorites)
const isFav = starIcon.dataset.favorites === "true";
if(isFav){
starIcon.src = "images/star-regular.png";
starIcon.dataset.favorites = "false";
removeFromFavorites(resource);
}
else{
starIcon.src = "images/star-solid.png";
starIcon.dataset.favorites = "true";
addToFavorites(resource);
}
}
function createResourceBox(resource){
const resourceBox = document.createElement("div");
resourceBox.id = "resource-box";
const resourceURL = document.createElement("a");
resourceURL.href = resource.url;
resourceURL.target = "_blank";
const resourceName = document.createElement("div");
resourceName.classList.add("resource-name");
resourceName.textContent = resource.name;
resourceURL.appendChild(resourceName)
const resourceDescription = document.createElement("div");
resourceDescription.classList.add("resource-description");
resourceDescription.textContent = resource.description;
const starIcon = document.createElement("img");
starIcon.src = "images/star-regular.png";
starIcon.alt = "favorites_Icon";
starIcon.classList.add("star-icon");
starIcon.dataset.favorites = "false";
resourceBox.appendChild(starIcon)
resourceBox.appendChild(resourceURL);
resourceBox.appendChild(resourceDescription);
starIcon.addEventListener("click", function(){
toggleFavorites(starIcon, resourceBox);
})
return resourceBox;
}
fetch("/data/studyresource.json")
.then(function(response){
return response.json();
})
.then(function(jsonData){
jsonData.sort(function(a,b){
return a.name.localeCompare(b.name);
});
jsonData.forEach(function(resource){
const box = createResourceBox(resource);
box.classList.add("custom-box");
jsonBoxes.appendChild(box);
});
})
.catch(function(error){
console.error("Error fetching study resource data:", error);
});
});
2
Answers
When you do
resource.cloneNode(true)
, you create new Nodes, which are no longer related (reference-wise) toresource
, even though their content appears the same (they are cloned…).Hence the error message when you attempt to remove the original
resource
from where you actually put its clone instead (favorites.appendChild(clone)
butfavorites.removeChild(resource)
).A simple solution could simply be to store a reference of the clone, e.g. alongside the
resource
directly, so that you can retrieve it to get the Node to be removed:The error message "Failed to execute ‘removeChild’ on ‘Node’: The node to be removed is not a child of this node." means that the
removeChild()
method is being called on a node that does not contain the child node that you are trying to remove.In your code, the
removeFromFavorites()
function is being called with theresource
parameter, which is an element from thejsonBoxes
NodeList. However, thefavorites
element is not a child of thejsonBoxes
NodeList.To fix this error, you need to make sure that the
resource
element is a child of the favorites element before you call theremoveChild()
method. You can do this by using thecontains()
method to check if thefavorites
element contains theresource
element.Here is the corrected code:
This code first checks if the
favorites
element contains theresource
element. If it does, then theremoveChild()
method is called to remove theresource
element from thefavorites
element.