Skip to content
Advertisement

Load data from firebase to HTML table

I have a FireBase realtime DB with some data that I would like to display in HTML grid. Structure of the DB is pretty simple: enter image description here

What I want to do is to have “id”, “First column”, “Second column”, “Third column” as a column headers and data from DB to be displayed under each respective header.

This is my HTML part:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>

  <!--Firebase SDK code below-->
  <script src="/__/firebase/8.2.6/firebase-app.js"></script>
  <script src="/__/firebase/8.2.6/firebase-analytics.js"></script>
  <script src="/__/firebase/8.2.6/firebase-database.js"></script>

  <!-- Initialize Firebase -->
  <script src="/__/firebase/init.js"></script>

  <script src="firebase.js"></script>

  <button onClick="readData()">Load data from FB</button>

  <table class="table table-striped" id="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>First column</th>
        <th>Second column</th>
        <th>Third column</th>
      </tr>
    </thead>
    <tbody>
</body>

</html>

JS here:

// Firebase reference
var database = firebase.database();
rootRef = database.ref('/');
itemsRef = database.ref('/Items/');

// Other vars
var pushLabels = ["id", "First column", "Second column", "Third column"];


function readData() {

  itemsRef.once('value', function (snapshot) {
    var arrayLen = pushLabels.length;
    var childKeyArr = [];

    var table = document.querySelector('#table tbody');

    snapshot.forEach(function (childSnapshot) {

      var childKey = childSnapshot.key;
      childKeyArr.push(childKey);
    });

    for (var i = 0; i < childKeyArr.length; i++) {

      var row = table.insertRow(-1);
      for (var j = 0; j < arrayLen; j++) {
        cell = row.insertCell(-1);
      };
    };

    for (var i = 0; i < childKeyArr.length + 1; i++) {
      database.ref('/Items/' + i).once('value', function (snapshot) {
        snapshot.forEach(function (childSnapshot) {
          var noha = childSnapshot.val();
          for (var i = 0; i < pushLabels.length; i++) {
            cell.innerHTML = noha;
          };
        });
      });
    }
  });
}

I think it’s quite “overcomplex”. I was able to create rows based on number of parent items in the DB (1,2,3 as shown on the DB hierarchy screenshots) and for each of the nodes I was able to retrieve the data into snapshot but I don’t know how to project it to the grid so each value is correctly displayed to it’s relevant column. The part where I put something into cell is obviously wrong in my code – I was just testing different ways.

Any help will be appreciated! Also if there is any better solution, some library that can do that in easier way, I would be happy if you can recommend. Thanks!!

Answer

Is there a fixed number of columns expected, or do you want to to create columns dynamically? Are your column headers already in the html file or are you looking to make them from the keys in the database? There’s column headers in your html file, yet you also have an array storing the same. They also match the keys of each child Item so it looks a little confusing.

Here’s a quick example of how you could get the table body, create a new row, create the cells, add the values from the database and then add the row to the table body.

var itemsRef = firebase.database().ref().child("Items");
var tableBody = document.querySelector('#table tbody');

function readData() {
    itemsRef.once('value', function (snapshot) {
        snapshot.forEach(function (item_snapshot) {
            //Create html elements, TRs, TD,s etc.
            var row = document.createElement("tr");
            var col1 = document.createElement("td");
            var col2 = document.createElement("td");
            var col3 = document.createElement("td");
            var col4 = document.createElement("td");
            //Add data to the new elements.
            col1.innerText = item_snapshot.key;
            col2.innerText = item_snapshot.child("First column").val();
            col3.innerText = item_snapshot.child("Second_column").val();
            col4.innerText = item_snapshot.child("Third_column").val();
            //Append the cells into the row and the row into the table body.
            row.appendChild(col1);
            row.appendChild(col2);
            row.appendChild(col3);
            row.appendChild(col4);
            tableBody.appendChild(row);
        });
    });
}

It sounds kinda like you want to have the keys of each child Item to be the column headers if I’m not misunderstanding you, but keep in mind that each child might not have the same nodes within it and you only want to load the headers once, rather than from each child Item.

Advertisement