0

I have a simple forEach loop in which I'm trying to append list items to an unordered list. However, when I run the script, I'm only seeing one list item being added. Can anyone explain why this is happening?

JS

let bookElement = document.getElementsByClassName("book");
let navElement = document.getElementsByTagName("nav")[0];
let unorderedList = document.createElement("UL");
let listItems = document.createElement("LI");
let book1 = new Book();
let book2 = new Book();
let booksArray = [book1, book2];

createNavigation(booksArray, navElement, unorderedList, listItems);

function createNavigation(booksArray, navElement, unorderedList, listItems){
    console.log(booksArray)
    booksArray.forEach(function(book){
        unorderedList.appendChild(listItems);
    })
    navElement.appendChild(unorderedList);
}

HTML

<body>
    <nav></nav>
    <div class="book"></div>
</body>

The log in the function is returning that there are two objects in the array.

2 Answers2

3

You only ever create one list item.

You then append it in multiple places.

Since an element can't exist in multiple places at the same time, each time you append it (after the first) you move it.

Use let listItems = document.createElement("LI"); inside your loop.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

Yes, there are two objects in the array, but you're adding the same element to the unorganised list twice. So, the second time it's added, the browser sees that the element is already there and doesn't add it again.

A better approach would be to simply create a new li element in each iteration of the loop:

function createNavigation(booksArray, navElement, unorderedList){
    console.log(booksArray)
    booksArray.forEach(function(book){
        let listItems = document.createElement("LI");
        unorderedList.appendChild(listItems);
    })
    navElement.appendChild(unorderedList);
}

Notice that I've removed the listItems parameter as the value passed into it is now unused.

You can take your program a step further, now, by doing something along these lines:

function createNavigation(booksArray, navElement, unorderedList){
    console.log(booksArray)
    booksArray.forEach(function(book){
        let listItems = document.createElement("LI");
        listItems.innerHTML = book.title;
        unorderedList.appendChild(listItems);
    })
    navElement.appendChild(unorderedList);
}

That will create a list of book titles, assuming you have titles stored in a title property in your Book constructor.

Oliver
  • 1,576
  • 1
  • 17
  • 31