I have a for loop that fetches code from another file and appends it to my website using the insertAdjacentHTML() method. After that it modifies the innerHTML of the freshly added piece of code. The code looks something like this:
for (let i = 0; i < 10; i++) {
fetch("myFile.html")
.then((obj) => obj.text())
.then((text) => {
document.getElementById("addContentHere").insertAdjacentHTML("beforeend", text);
document.getElementsByClassName("elementInAddedContent")[i].innerHTML = "Modified content";
});
}
In my website I have the following code:
<div id="addContentHere"></div>
And the HTML that I’m fetching is something like this:
<div class="addedElement">
<div class="elementInAddedContent"></div>
</div>
The problem is that the computer reaches the innerHTML before the element has been added and so I get the Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'innerHTML') error. I have tried to wrap the code in a promise and add if (i == 10) resolve("Content loaded"); and then have a placeholder variable that waits for the resolve (placeholder = await promise;). But the code just resolves immediately on the last run of the for loop and doesn’t wait for the content to get added.
>Solution :
Your loop is trying as fast as possible to read a file, update the DOM and read again and update again. There is no control over what is happening since Fetch is async. I still do not understand why you had a loop around getting ONE file..
Perhaps you meant to do this?
I give the DOM 100 ms to be updated
fetch("myFile.html")
.then((obj) => obj.text())
.then((text) => {
document.getElementById("addContentHere").insertAdjacentHTML("beforeend", text);
setTimeout(() => document.querySelectorAll(".elementInAddedContent").forEach(el => el.textContent = "Modified content"), 100);
});