skip to Main Content

I’m not very proficient with JS/HTML. I needed to get the table in JSON from Firebase and show it nicely using DataTables.
I have a working code getting data from Firebase after JSON.stringify as:

[{
    "Rings": 0,
    "P_Bars": 0,
    "First_Name": "Jane",
    "Last_Name": "Dow",
    "Vault": 10,
    "Number": 101,
    "H_Bar": 0,
    "Level": "4_A",
    "Pommel": 11.402,
    "Floor": 0
}, {
    "Pommel": 12.5,
    "Vault": 7,
    "Floor": 11.5,
    "Level": "6_Optional",
    "P_Bars": 10,
    "H_Bar": 0,
    "Number": 102,
    "First_Name": "Steve",
    "Last_Name": "Dark",
    "Rings": 12
}]

And I’m having the following error:

DataTables warning: table id=test – Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1

My JS code:

async function GetAllDataRealtime() {
  const dbRef = collection(db, "Gymnasts");

  onSnapshot(dbRef, (querySnapshot) => {
    var gymnasts = [];
    querySnapshot.forEach((doc) => {
      gymnasts.push(doc.data());
    });
    return JSON.stringify(gymnasts);
  });
}

var testdata = GetAllDataRealtime();

$(document).ready(function () {
  $("#test").DataTable({
    ajax: {
      "data": testdata,
      "dataType": "json",
    },
    columns: [
      { data: "Number" },
      { data: "First_Name" },
      { data: "Last_Name" },
      { data: "Rings" },
      { data: "Floor" },
      { data: "Pommel" },
      { data: "H_Bar" },
      { data: "P_Bars" },
      { data: "Vault" },
    ],
  });
});

And HTML *(I don’t think the problem is here though)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Test</title>

    <script src="https://code.jquery.com/jquery-3.7.0.js"></script>
    <link
      rel="stylesheet"
      href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.css"
    />
    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.js"></script>
    <script type="module" src="script.js"></script>
    <!-- <script src="db.js"></script> -->
  </head>
  <body>
    <table id="test" class="display" style="width: 100%">
      <thead>
        <tr>
          <th>Number</th>
          <th>First_Name</th>
          <th>Last_Name</th>
          <th>Rings</th>
          <th>Floor</th>
          <th>Pommel</th>
          <th>H_Bar</th>
          <th>P_Bars</th>
          <th>Vault</th>
        </tr>
      </thead>
    </table>
  </body>
</html>

I tried to use a dedicated .json file an it works.
Based on https://datatables.net/manual/tech-notes/1 *(from the Error message) I investigated the XHR/Request-Response and I cannot even see a proper response in the logs although consoling the "testdata" showing the correct array. Tested with JSON validator – all good. It feels I’m missing something here.

2

Answers


  1. Data is loaded from Firestore (and most cloud APIs) asynchronously, but your code fails to handle that.

    You have two asynchronous events in your code:

    1. The document itself loads asynchronously.
    2. The data from Firestore is loaded asynchronously.

    Your code needs to handle this asynchronous nature, for example: by only creating the data table when the the document is ready and when the data has been loaded from Firestore.

    In code that could be done like this:

    $(document).ready(function () {
      const dbRef = collection(db, "Gymnasts");
    
      onSnapshot(dbRef, (querySnapshot) => {
        var gymnasts = [];
        querySnapshot.forEach((doc) => {
          gymnasts.push(doc.data());
        });
    
        $("#test").DataTable({
          ajax: {
            "data": gymnasts,
            "dataType": "json",
          },
          columns: [
            { data: "Number" },
            { data: "First_Name" },
            { data: "Last_Name" },
            { data: "Rings" },
            { data: "Floor" },
            { data: "Pommel" },
            { data: "H_Bar" },
            { data: "P_Bars" },
            { data: "Vault" },
          ],
        });
    
      });
    });
    

    So here we only start loading the data once the document is read, and then set the data table once the data is available. Since you’re using an onSnapshot realtime listener, the data table will be updated when the underlying data is updated.


    I highly recommend reading up and taking some tutorials on asynchronous behavior before continuing, as this is an incredibly common source of confusion – and you’re likely to get stuck on it many times until you grok async code.

    Login or Signup to reply.
  2. I have parsed the JSON data and put into the DataTable as described in the documentation and it works for me!

    Check out the below solution:

    let data = JSON.parse("[{"Rings": 0,"P_Bars": 0,"First_Name": "Jane","Last_Name": "Dow","Vault": 10,"Number": 101,"H_Bar": 0,"Level": "4_A","Pommel": 11.402,"Floor": 0}, {"Pommel": 12.5,"Vault": 7,"Floor": 11.5,"Level": "6_Optional","P_Bars": 10,"H_Bar": 0,"Number": 102,"First_Name": "Steve","Last_Name": "Dark","Rings": 12}]");
    
    $(document).ready(function () {
      new DataTable('#test', {
        data: data,
        columns: [
          { data: "Number" },
          { data: "First_Name" },
          { data: "Last_Name" },
          { data: "Rings" },
          { data: "Floor" },
          { data: "Pommel" },
          { data: "H_Bar" },
          { data: "P_Bars" },
          { data: "Vault" },
        ]
      });
    });
    <script src="https://code.jquery.com/jquery-3.7.0.js"></script>
    <link href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.css" rel="stylesheet"/>
    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.js"></script>
    <table id="test" class="display" style="width: 100%">
      <thead>
        <tr>
          <th>Number</th>
          <th>First_Name</th>
          <th>Last_Name</th>
          <th>Rings</th>
          <th>Floor</th>
          <th>Pommel</th>
          <th>H_Bar</th>
          <th>P_Bars</th>
          <th>Vault</th>
        </tr>
      </thead>
    </table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search