简体   繁体   中英

I'm facing the problem while setting the innerHTML of the <tbody> tag. After selecting it using the document.getElementById, it shows me the error

All I'm doing was getting the tbody tag from my html code using the document.getElementByID("tableBody") and trying to add some rows using the javascript. But whenever I try to set the innerHTML property of the tbody tag, it shows me this error.

index2.js:38 Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
    at Display.add (index2.js:38)
    at HTMLButtonElement.<anonymous> (index2.js:90)

I don't know why I'm getting this error I've revisted my code multiple times. Please help someone

HTML code:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Reading</title>

    <!-- CSS of the bootstrap  -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"
        integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

    <!-- Custom CSS  -->
    <link rel="stylesheet" href="CSS/style.css">

    <!-- Google Fonts  -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Leckerli+One&display=swap" rel="stylesheet">

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@400;700&display=swap" rel="stylesheet">

    <!-- Fontawesome cdn  -->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">

</head>

<body>

    <!-- Navbar Code  -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">

        <a href="#" class="navbar-brand navbar-expand-lg navbar-dark bg">READINGS</a>

        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01"
            aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div id="navbarTogglerDemo01" class="collapse navbar-collapse">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item"> <a href="#" class="nav-links">Home</a></li>
            </ul>
        </div>
    </nav>

    <!-- library detail code starts  -->
    <div class="container-fluid form-section">
        <h1>My Reading Library</h1>

        <!-- Form section  -->
        <div class="container form-holder-div">

            <form id="libraryForm">
                <div class="form-group row">
                    <label for="bookName" class="col-sm-2 col-form-label">Book Name</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="bookName">
                    </div>
                </div>
                <div class="form-group row">
                    <label for="AuthorName" class="col-sm-2 col-form-label">Author of the book</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="authorName">
                    </div>
                </div>
                <fieldset class="form-group row">
                    <legend class="col-form-label col-sm-2 float-sm-left pt-0">Type</legend>
                    <div class="col-sm-10">
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="bookType" id="Fiction" value="fiction"
                                checked>
                            <label class="form-check-label" for="fiction">
                                Fiction
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="bookType" id="Programming"
                                value="programming">
                            <label class="form-check-label" for="Programming">
                                Programming
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="bookType" id="Cooking" value="cooking">
                            <label class="form-check-label" for="Cooking">
                                Cooking
                            </label>
                        </div>
                    </div>
                </fieldset>
                <div class="form-group row">
                    <div class="col-sm-10">
                        <button type="submit" class="btn btn-primary" style="font-weight: 700;" id="addButton">Add Book</button>
                    </div>
                </div>
            </form>
        </div>
    </div>

    <!-- table section  -->
    <div class="container-fluid table-section" id="tableArea">
        <table class="table">
            <thead class="thead-dark">
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Book Name</th>
                    <th scope="col">Author Name</th>
                    <th scope="col">Type</th>
                    <th scope="col">Operation</th>
                </tr>
            </thead>

            <tbody id="tableBody">
                
            </tbody>
        </table>
    </div>

    <div class="footer-section">
        <h1><i class="far fa-copyright"> </i> Made with <i class="far fa-laugh-wink"></i> by TheNullPerson</h1>
    </div>

    <!-- This is the bootstrap javaScript -->
    <script src="javascript/index2.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
        integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"
        integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2"
        crossorigin="anonymous"></script>
</body>

</html>

JavaScript code:

var bookObj = [];
/*  Display Class with the following methods:
1) .add(book) => to add book(array of book objects) to the table element 
2) .clear => to clear the element from the text fields
*/
function Display() {
}
// .add() method 
Display.prototype.add = function () {
    let bookElements = localStorage.getItem("books");
    if (bookElements === null) {
        bookObj = [];
    } else {
        bookObj = JSON.parse(bookElements);
        console.log(typeof bookObj);
    }

    console.log(bookObj);
    let html = "";
    let Element;
    if (bookObj.length === 0) {
        html = "<h1>Please add some content from above section</h1>";
        Element = document.getElementById("tableArea");
        Element.innerHTML = html;
    } else {
        bookObj.forEach(function(element, index) {
            
            html += `<tr>
            <th scope="row">${index + 1}</th>
            <td>${element.bookName}</td>
            <td>${element.authorName}</td>
            <td>${element.type}</td>
            <th scope="col"> <button class="btn btn-primary"> Remove </button> </th>
            </tr>`;
        });
        Element = document.getElementById("tableBody");
        // console.log(typeof tableElement);
        Element.innerHTML = html;
    }
    html = "";
}

// .clear() method
Display.prototype.clear = function(){
    let form = document.getElementById("libraryForm");
    form.reset();
}
var display = new Display();    // Display object to access different display methods
display.add();
display.clear();

/*
    Book class with the property
    1) bookName = Name of the book
    2) authorName = Name of the author
    3) type = Type of book
*/ 
function Book(bookName, authorName, type){
    this.bookName = bookName;
    this.authorName = authorName;
    this.type = type;
}

let addBook = document.getElementById("addButton");
addBook.addEventListener("click", function (e){
    
    e.preventDefault();
    let bookName = document.getElementById("bookName").value;
    let authorName = document.getElementById("authorName").value;
    let type;
    let fiction = document.getElementById("Fiction");
    let programming = document.getElementById("Programming");
    let cooking = document.getElementById("Cooking");
    
    if (fiction.checked){
        type = fiction.value;
    } else if (programming.checked) {
        type = programming.value;
    }
    else if (cooking.checked) {
        type = cooking.value;
    }
    
    let book = new Book(bookName, authorName, type);
    bookObj.push(book);
    // console.log(typeof book)
    localStorage.setItem("books", JSON.stringify(bookObj));
    console.log(typeof bookObj);
    
    display.add();
    
    display.clear();
})

This is because when bookObj is empty, you obliterate the <div> that contains the table (and therefore the tbody ).

Then, once you add a book to bookObj there is no longer a table on the page to find, so Element is null .

Consider hiding the content you don't want to appear rather than obliterating it.

Your code is okay and running well but the reason why you are not seeing the table is that you are assigning two different values to the Element identifier. Inside the execution context , where javascript is executed, the operations are done from top to bottom . Your code assigns value to the Element identifier inside the if condition after which the element is removed from the execution context.

Your javascript code should look like this after removing the first assignment of the Element identifier inside the if statement .

var bookObj = [];
   /*  Display Class with the following methods:
   1) .add(book) => to add book(array of book objects) to the table element 
   2) .clear => to clear the element from the text fields*/

   function Display() {
   }
  // .add() method 

   Display.prototype.add = function () {
   let bookElements = localStorage.getItem("books");
   if (bookElements === null) {
    bookObj = [];
  } else {
    bookObj = JSON.parse(bookElements);
    console.log(typeof bookObj);
}

console.log(bookObj);
let html = "";
let Element;
if (bookObj.length === 0) {
    html = "<h1>Please add some content from above section</h1>";
    Element.innerHTML = html;
} else {
    bookObj.forEach(function(element, index) {
        
        html += `<tr>
        <th scope="row">${index + 1}</th>
        <td>${element.bookName}</td>
        <td>${element.authorName}</td>
        <td>${element.type}</td>
        <th scope="col"> <button class="btn btn-primary"> Remove </button> </th>
        </tr>`;
    });
    Element = document.getElementById("tableBody");
    // console.log(typeof tableElement);
    Element.innerHTML = html;
}
html = "";
}

  // .clear() method
  Display.prototype.clear = function(){
let form = document.getElementById("libraryForm");
form.reset();
}
var display = new Display();    // Display object to access different display methods
display.add();
display.clear();

/*
Book class with the property
1) bookName = Name of the book
2) authorName = Name of the author
3) type = Type of book */ 
 function Book(bookName, authorName, type){
this.bookName = bookName;
this.authorName = authorName;
this.type = type;
}

let addBook = document.getElementById("addButton");
addBook.addEventListener("click", function (e){

e.preventDefault();
let bookName = document.getElementById("bookName").value;
let authorName = document.getElementById("authorName").value;
let type;
let fiction = document.getElementById("Fiction");
let programming = document.getElementById("Programming");
let cooking = document.getElementById("Cooking");

if (fiction.checked){
    type = fiction.value;
} else if (programming.checked) {
    type = programming.value;
}
else if (cooking.checked) {
    type = cooking.value;
}

let book = new Book(bookName, authorName, type);
bookObj.push(book);
// console.log(typeof book)
localStorage.setItem("books", JSON.stringify(bookObj));
console.log(typeof bookObj);

display.add();

display.clear();
})

It works and displays the table on the UI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM