Search code examples
javascriptremovechild

Replacing more than one child node when using replaceChild


I am calling an API to generate a list for cocktails. There are two lists. The first one is a drink ingredient list. The second is a drink measurement list.

What I want to do is when I click my generate random cocktail button it replaces all of the text that is generated through the API and puts it into a list, what is happening is when I press the button again it is only populating the last item on the list even though I can see all of the item when I console log.

Here is the current JavaScript:

function getMeasure(data) {
    for (i = 1; i <= 15; i++) {

        if (data.drinks[0][`strMeasure${i}`]) {
            // console.log(data.drinks[0][`strMeasure${i}`])
            var drinkMeasureDiv = document.createElement('li');
            drinkMeasureDiv.classList.add('drink-measure')
            var drinkMeasureText = document.createTextNode(data.drinks[0][`strMeasure${i}`] );
            drinkMeasureDiv.appendChild(drinkMeasureText);
            drinkMeasureEl.appendChild(drinkMeasureDiv);

            var item = document.getElementById("measure-list");
            item.replaceChild(drinkMeasureDiv, item.childNodes[0]);
        }
    }
}

Solution

  • By calling item.replaceChild(drinkMeasureDiv, item.childNodes[0]) you are replacing the same element up to 16 times (hence only the last entry is visible, because it is the only one not overwritten). This might be what you intend:

    function getMeasure(data) {
        const list = document.getElementById("measure-list");
        list.childNodes.forEach((n) => n.remove());
        const drink = data.drinks[0];
    
        for (let i = 1; i <= 15; i++) {
            if (drink[`strMeasure${i}`]) {
                const drinkMeasureDiv = document.createElement("li");
                drinkMeasureDiv.classList.add("drink-measure");
                const drinkMeasureText = document.createTextNode(drink[`strMeasure${i}`]);
                drinkMeasureDiv.appendChild(drinkMeasureText);
                list.appendChild(drinkMeasureDiv);
            }
        }
    }
    

    by first clearing all the childnodes of .measure-list and then appending them back one by one. drinkMeasureEl was not defined in your example, so I took the liberty to remove it. Based on this example you may put it back if necessary.