I’m building a fictional webshop for plants and currently I’m working on filtering them combining different options (light demand, water demand, toxic etc.).
Using a separate JSON file, I’m creating cards based on the data after the JSON file was fetched:
getPlants().then((data) => {
data.forEach((data) => {
plantcards.insertAdjacentHTML(
"afterbegin",
`<article class="plantcard ${getPlantLight(data.Light)} ${getPlantWater(
data.WaterDemand
)}wasser ${getPlantToxic(data.Toxic)}">
<div class="article-wrapper">
<figure>
<img src="../images/plant_types/${data.Image}" alt="${data.Name}" />
</figure>
<div class="article-body">
<h2>${data.Name}</h2>
<h3>${data.NameLatin}</h3>
<p>
Standort: ${getPlantLight(data.Light)}<br/>
Wasserbedarf: ${getPlantWater(data.WaterDemand)}<br/>
Schwierigkeitsgrad: ${getPlantMaintenance(data.Maintenance)}<br/>
Giftig: ${getPlantToxic(data.Toxic)}<br/>
</p>
<a href="#" class="read-more">
Read more <span class="sr-only">about this is some title</span>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</a>
</div>
</div>
</article>`
);
});
});
let allPlantcards = Array.from(document.querySelectorAll(".plantcard"));
allPlantcards
is always an empty array with a length of 0, I guess because allPlantcards
is created before or while the cards are loaded.
I also tried to place let allPlantcards = Array.from(document.querySelectorAll(".plantcard"));
within other functions but then I can’t use them outside of the function, right?
2
Answers
It sounds like you’re dealing with a timing issue where you’re trying to select elements that haven’t been added to the DOM yet because your
document.querySelectorAll(".plantcard")
call is executed before the cards are inserted.Here is the modest proposition of the working code:
This HTML template sets up a basic structure and functionality for displaying and managing plant cards in a webshop. Adjust the paths to images and data as needed for your application.
getPlants()
simulates fetching plant data. Replace this with your actual API call.getPlantLight()
,getPlantWater()
,getPlantToxic()
, andgetPlantMaintenance()
determine CSS classes based on plant attributes.displayPlantCards(data)
adds plant cards to the DOM and selects them afterward.The problem you’re running into is really due to the fact that querySelectorAll is called before the elements have been added to the DOM using insertAdjacentHTML. To solve this problem, you need to make sure that the code to select the elements is executed after all the plant cards have been added to the DOM.
Simply move the querySelectorAll call to the end of getPlants().then(…) so that it is executed after all the cards have been added to the DOM: