Search code examples
javascriptdominnerhtml

How can i insert an element in the HTML BODY using Js then select the same element using Js and then append some more data into it?


I am trying to make a single page web app and i have different tabs example is unapproved tab . when i click on this tab i prevent the default using action using js then i get the container element of the page

let container = document.getElementById('container');

i then insert a table in the container

container.innerHTML = `
        <table id="table" class="table">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">First</th>
                    <th scope="col">Last</th>
                    <th scope="col">Handle</th>
                </tr>
            </thead>
            <tbody id="tablebody">

            </tbody>
        </table>
        `;

once that is done i fetch some data using ajax and insert then into the table body using js.

     try {
        http.get('../includes/unapproved.inc.php')
            .then(res => {
                //check if the response if ok
                console.log(res);
                let rows = '';
                for (let i in res) {
                    rows += ` 
               <tr>
                    <td>${res[i].user_user_id} <td>
               <tr>
               `
                }
                tablebody.innerHTML = rows;
                console.log(table);

            });
    } catch (error) {
        console.log(error);

    }

But when i try to insert the data i get this error

pages.js:51 Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of null
    at pages.js:51

i do not understand why i am getting this error yet i have already inserted the table in the DOM.

below is the whole code

import { FETCH } from "./fetch.js";

export class PAGES {
    constructor() {
        this.unapproved = document.getElementById('unapproved');
    }
    events() {
        this.unapproved.addEventListener('click', (e) => {
            e.preventDefault();
            this.unapprovedPage();

        })
    }
    unapprovedPage() {
        let container = document.getElementById('container');
        let table = document.getElementById('table');
        let tablebody = document.getElementById('tablebody');
        container.innerHTML = `
        <table id="table" class="table">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">First</th>
                    <th scope="col">Last</th>
                    <th scope="col">Handle</th>
                </tr>
            </thead>
            <tbody id="tablebody">

            </tbody>
        </table>
        `;

        const http = new FETCH;

        try {
            http.get('../includes/unapproved.inc.php')
                .then(res => {
                    //check if the response if ok
                    console.log(res);
                    let rows = '';
                    for (let i in res) {
                        rows += ` 
                   <tr>
                        <td>${res[i].user_user_id} <td>
                   <tr>
                   `
                    }
                    tablebody.innerHTML = rows;
                    console.log(table);

                });
        } catch (error) {
            console.log(error);

        }
    }


}

Solution

  • You are selecting the #tablebody element before it is in the document. So the result will always be null.

    First add the innerHTML content of the container element.

    container.innerHTML = `
    <table id="table" class="table">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">First</th>
                <th scope="col">Last</th>
                <th scope="col">Handle</th>
            </tr>
        </thead>
        <tbody id="tablebody">
    
        </tbody>
    </table>
    `;
    

    And then select the element from the container using querySelector.

    let tablebody = container.querySelector('#tablebody');
    

    Also, prevent using ID's when appending dynamic content and instead use classes. Your page will not work as expected when there is more than one element with the same ID is on the page.