Display the content of my Local Storage using DOMContentLoaded event

I’m working on a Library App and I need to display the content of my Local Storage on the main page. I know how to get the array of books but I’m having hard time trying to show it on the page inside a table.

The table is created inside another function when the user clicks a submit button on a form (addBookToList()).

When I call the function addBookToList inside the DOMContentLoaded event, only the last book in the storage array is displayed on the page.

HTML:

    <form action="#" class="form">
        <label for="title">Title</label>
        <input type="text" id="title" required>
        <label for="author">Author</label>
        <input type="text" id="author" required>
        <label for="num-pages">No. of pages</label>
        <input type="number" id="num-pages" required>
        <br>
        <span>Have you read this book?</span>
        <br>
        <input type="radio" name="radio" id="yes" value="yes" checked>
        <label for="yes" class="yes">Yes</label>
        <input type="radio" name="radio" id="no" value="no">
        <label for="no" class="no">No</label>
        <div class="button-div">
            <button id="add-btn" type="submit">SUBMIT</button>
        </div>
    </form>
</div>

<div class="table-box">
    <hr>
    <table>
        <thead>
            <tr>
                <th>Title</th>
                <th>Author</th>
                <th>No. of pages</th>
                <th>Read</th>
            </tr>
        </thead>
        <tbody class="list"></tbody>

    </table>
</div>

JAVASCRIPT:

// Get values
let formContainer = document.querySelector('.form-div');
let form = document.querySelector('.form');
let addBtn = document.querySelector('#add-btn');
let btnNewBook = document.querySelector('#addBook-btn');

// Book constructor
function Book(author, title, pages, read) {
this.title = title;
this.author = author;
this.pages = pages;
this.read = read;
}

// Empty array to store books
let myLibrary = [];

// Form event listener
form.addEventListener('submit', (e) => {
e.preventDefault();

  // Hide form and show home page
  document.querySelector('.table-box').style.display = 'block';
  document.querySelector('.para-div').style.display = 'block';
  form.style.display = 'none';

  // Get values from User
  let title = document.querySelector('#title').value;
  let author = document.querySelector('#author').value;
  let pages = document.querySelector('#num-pages').value;
  let read = getRead();

  // Instantiate book
  const book = new Book(author, title, pages, read);

  // Push book to the library, show it on the UI and clear the form
  myLibrary.push(book);

  addBookToList();

  // Add book to Local Storage
  addBook();

  // Show success alert
  showAlert('Book added!', 'success');

  // Clear form
  form.reset();

});

// Add book to list
function addBookToList() {
  const list = document.querySelector('.list');

  // Create new row element
  const row = document.createElement('tr');

  // Loop through myLibrary array
  myLibrary.forEach(value => {

    // Add the book to the table
        row.innerHTML = `
        <td>${value.title}</td>
        <td>${value.author}</td>
        <td>${value.pages}</td>
        <td>${value.read}</td>
        <td><a href="#" class="btn delete">X</a></td>`;
});

// Append the row to list
list.appendChild(row);
}

// Storage
function getLibrary() {
   if(localStorage.getItem('myLibrary') === null) {
     myLibrary = [];
   } else {
     myLibrary = JSON.parse(localStorage.getItem('myLibrary'));
   }
   return myLibrary;
 }

 function addBook() {
   localStorage.setItem('myLibrary', JSON.stringify(myLibrary));
 }

 function removeBook(index) {
   getLibrary();
   let removed = myLibrary.indexOf(index);
   myLibrary.splice(removed, 1);
   localStorage.setItem('myLibrary', JSON.stringify(myLibrary));
 }

 // Load page event listener
 document.addEventListener('DOMContentLoaded', function displayBooks(){

   getLibrary();
   addBookToList();

 });

I don’t think you gave us all the HTML. In your JS you have

document.querySelector('.para-div').style.display = 'block';

But I don’t see any element in the HTML with class para-div.

Sorry:

<div class="main-div">
    <div class="para-div">
        <p>Click the button below and add a new book to the list</p>
        <button id="addBook-btn">+ ADD BOOK</button>
</div>

Now I’m getting the following JS error:

Uncaught ReferenceError: getRead is not defined

And ya, I don’t see getRead() defined anywhere.

I don’t want to sound like a jerk here, but you are making me do a lot of work to try and help you. I think you need to get this in working order first and put it in a repository (like github) where we can see all of your code so we don’t have to keep going back and forth like this. Or since you aren’t transpiling here, you could just host everything on a server somewhere.

Bottom line, you need to make it easy for us to help you.

You’re right, I forgot one section…sorry I’m still new to coding, but anyway this is the link to the github repository:

Much better. I cloned your repo and when I opened index.html I got the following JS error:

Uncaught InternalError: too much recursion
    displayBooks file:///home/bbsmooth/test/LibraryApp/app.js:23

So I think you still have some cleaning up to do.

I made some changes inside the DOMContentLoaded and removed the addBookToList so it should work now. Also, I still get only the last book displayed.

Let me know if it works.

I think I solved it…I was appending the row outside the loop and I put it inside instead and it seems working now…