James B
James B

Reputation: 452

Fetch only returning last item in loop

I feel like I'm missing something very basic here... The summary is that I have an array of 10 cards which correspond to 10 different collections on my website. Each card has an image element. I want to replace that card with a new card where the image's source and a few other items have changed (and also I've added animations).

The problem is that my fetch for the new image source, which I grab from another site (website/collectionName/configs.ini) is only working for the last card in the loop.

let cardsOnly = document.createElement("div");
cardArray = document.querySelectorAll('.cards');
cardArray.forEach(function(card) {
    //do a bunch of stuff to the card like add title and remove old classes
    card.appendChild(cardTitleDiv);
    collectionName = //grabbed from this page
    bgImage = document.createElement("img");
    let configWebsite = website/collectionName/configs.ini

    const request = async () => {
        const response = await fetch(configWebsite)
        const text = await response.text() //so now I have the text from the config website
        newImgSource = //extracted from text
        console.log(collectionName + " " + newImgSource);
        bgImage.setAttribute("src", newImgSource);
        console.log(bgImage);
        card.appendChild(bgImage);
    }
    request();
    //do a bunch of other stuff to the card like add description div
    card.appendChild(descriptionDiv);
    cardsOnly.appendChild(card); //add all cards to cardsOnly div
}
//append the cardsOnly div to my wrapper on the page. 

When the page loads, the cards all have the correct titles, the correct descriptions, and here's the weird part... the first console.log, for each of the 10 cards in the array, this DOES output the CORRECT collectionName AND the CORRECT new image source which I just fetched and extracted....

but when I look inside the cardsOnly div, the only card in there with an <img> element is the last card. And the console.log(bgImage) that's inside request()... well that keeps outputting the <img> element that corresponds to the last (10th) card.


My console looks like this:

collection1: correct new image source for collection 1
<img> element for collection 10 with correct img src for collection 10

collection2: correct new img src for collection 2
<img> element for collection 10 with correct img src for collection 10

etc..
etc.. 

Why is this happening?

Upvotes: 0

Views: 457

Answers (1)

Holli
Holli

Reputation: 5082

Possibly a scoping problem. bgImage is never declared and has therefore function scope like variables declared with var. That means you are working on the same bgImage in every iteration. You should use let so you get block scope.

let bgImage = document.createElement("img");

Upvotes: 2

Related Questions