1

i am using a table to display data from a firebase, the problme is that everytime i update the data, i get a duplicate of the table instead of reloaded data.

I have tried several different ways but none work. Also i am not an experienced programmer. this is my code. The entire function myFunction is called every-time the value of select is changed.

<html>
<head>
  <title>OSA</title>
  <link href="https://fonts.googleapis.com/css?family=Nunito:400,600,700" rel="stylesheet">
  <link rel="stylesheet" href="style.css" />
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

</head>
<body>
<div>

    <select id="mySelect" class="mySelect" onchange="getData()">
     <option>Select Class</option>
      <option value="ArtificialIntelligence">Artificial Intelligence</option>
      <option value="MachineLearning">Machine Learning</option>
      <option value="NaturalLanguageInterface">Natural Language Interface</option>
    </select>

  </div>

<div class="studentTable-div" id="table-div">
    <p>
      <h2 class="h2" id="tblText""></h2>
    </p>

      <button class="button" onclick="refresh()">Refresh</button>

      <table id="tbl_users_list" class="w3-table w3-striped w3-bordered">
        <tr>
          <td>ID</td>
          <td>NAME</td>
          <td>PRESENT</td>
        </tr>
      </table>
    </div>

</body>


<script>

  //creating reference to the database.
    var database = firebase.database();
    var x;



  function getData() {

    resetTable();

      var tblUsers = document.getElementById('tbl_users_list');
      x = document.getElementById("mySelect").value;
      var databaseRef = firebase.database().ref('Classes/'+x+'/students');
      var rowIndex = 1;

      databaseRef.once('value', function(snapshot) {

      snapshot.forEach(function(childSnapshot) {

      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();


      var row = tblUsers.insertRow(rowIndex);
      var cellId = row.insertCell(0);
      var cellName = row.insertCell(1);
      var cellPresent = row.insertCell(2);


      cellId.appendChild(document.createTextNode(childKey));
      cellName.appendChild(document.createTextNode(childData.name));
      cellPresent.appendChild(document.createTextNode(childData.present));

      rowIndex = rowIndex + 1;     

      });
    });

    var text = x.split(/(?=[A-Z])/).join(" ");

    document.getElementById('tblText').innerHTML = "Students enroled for " + text;


  }

  function setText(){

    document.getElementById('tblText').innerHTML = "Students enroled for " + text;
  }


  function resetTable(){

    var table = document.getElementById("tbl_users_list");
    //or use :  var table = document.all.tableid;
    for(var i = table.rows.length - 1; i > 0; i--)
    {
        table.deleteRow(i);
    }
  }


</script>

<script src="https://www.gstatic.com/firebasejs/5.9.1/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "AIzaSyBAV157BePawASuItu_Ycvv8p96SQcuFVg",
    authDomain: "osattendance-352c4.firebaseapp.com",
    databaseURL: "https://osattendance-352c4.firebaseio.com",
    projectId: "osattendance-352c4",
    storageBucket: "osattendance-352c4.appspot.com",
    messagingSenderId: "91858851284"
  };
  firebase.initializeApp(config);
</script>
<script src="index.js"></script>
<script src="https://www.puck-js.com/puck.js"></script>

</body>
</html>


All i need is for the table to stay as it is and only reload the fields that are updated. Thanks

Ok so as you may see, the following is my main screen . with the html select the user may select different classes, data in the table should display accordingly, instead, everytime i select different class, the table just gets bigger and bigger as it loads the data which i have selected.

This is my json file for the database, nothing more than just number of classes with students.

{
  "Classes" : {
    "ArtificialIntelligence" : {
      "code" : "code",
      "students" : {
        "1212" : {
          "name" : "jacob",
          "present" : "false",
          "surname" : "kalas"
        },
        "2323" : {
          "name" : "chanelle",
          "present" : "true",
          "surname" : "lindsay"
        },
        "3434" : {
          "name" : "adam",
          "present" : "true",
          "surname" : "smith"
        },
        "4545" : {
          "name" : "aroon",
          "present" : "false",
          "surname" : "lindsay"
        },
        "5656" : {
          "name" : "derek",
          "present" : "false",
          "surname" : "salak"
        },
        "6767" : {
          "name" : "ernest",
          "present" : "false",
          "surname" : "brown"
        },
        "7878" : {
          "name" : "liam",
          "present" : "false",
          "surname" : "day"
        },
        "8989" : {
          "name" : "sebastian",
          "present" : "false",
          "surname" : "mcgregor"
        },
        "9191" : {
          "name" : "paul",
          "present" : "false",
          "surname" : "hemingway"
        },
        "9898" : {
          "name" : "kuba",
          "present" : "false",
          "surname" : "kalas"
        }
      }
    },
    "MachineLearning" : {
      "code" : "code",
      "students" : {
        "1111" : {
          "name" : "student1",
          "present" : "true",
          "surname" : "kalas"
        },
        "2222" : {
          "name" : "student1",
          "present" : "false",
          "surname" : "lindsay"
        },
        "3333" : {
          "name" : "jim",
          "present" : "false",
          "surname" : "smith"
        },
        "4444" : {
          "name" : "aroon",
          "present" : "false",
          "surname" : "lindsay"
        },
        "5555" : {
          "name" : "derek",
          "present" : "false",
          "surname" : "salak"
        },
        "6666" : {
          "name" : "ernest",
          "present" : "false",
          "surname" : "brown"
        },
        "7777" : {
          "name" : "liam",
          "present" : "false",
          "surname" : "day"
        },
        "8888" : {
          "name" : "sebastian",
          "present" : "false",
          "surname" : "mcgregor"
        },
        "9191" : {
          "name" : "paul",
          "present" : "false",
          "surname" : "hemingway"
        },
        "9999" : {
          "name" : "kuba",
          "present" : "false",
          "surname" : "kalas"
        }
      }
    },
    "NaturalLanguageInterface" : {
      "code" : "code",
      "students" : {
        "1212" : {
          "name" : "kate",
          "present" : "false",
          "surname" : "kalas"
        },
        "2323" : {
          "name" : "Tom",
          "present" : "true",
          "surname" : "lindsay"
        },
        "3434" : {
          "name" : "pauly",
          "present" : "true",
          "surname" : "smith"
        },
        "4545" : {
          "name" : "aroon",
          "present" : "false",
          "surname" : "lindsay"
        },
        "5656" : {
          "name" : "derek",
          "present" : "false",
          "surname" : "salak"
        },
        "6767" : {
          "name" : "ernest",
          "present" : "false",
          "surname" : "brown"
        },
        "7878" : {
          "name" : "liam",
          "present" : "false",
          "surname" : "day"
        },
        "8989" : {
          "name" : "sebastian",
          "present" : "false",
          "surname" : "mcgregor"
        },
        "9191" : {
          "name" : "paul",
          "present" : "false",
          "surname" : "hemingway"
        },
        "9898" : {
          "name" : "kuba",
          "present" : "false",
          "surname" : "kalas"
        }
      }
    }
  }
}
Quba
  • 11
  • 6
  • Before your `snapshot.forEach...` you can delete all rows in your table (except for the header row). – Andrew Lohr Mar 27 '19 at 19:23
  • may you please show me how if you know? I have tried several ways and nothing. – Quba Mar 27 '19 at 19:38
  • 1-You want the existing data from the table to be removed and new data to be updated in that place?? or 2- you want the old data in the table to be present and the new data to be added below under the existing one?? How is that you want?? – Fire-In-D-Hole Mar 27 '19 at 19:41
  • 1-I want the existing data from the table to be removed and new data to be updated in that place. – Quba Mar 27 '19 at 19:44
  • can you show us your realtime db data ..Export the realtime data from your database and paste it [Click me to export data from Database](https://stackoverflow.com/questions/47182297/how-do-i-export-data-from-firebase-realtime-database/47182298#47182298) . Also can you show us the duplicate data that is being added into the Html and what data are you expecting to be shown in the Table?? With the function code you have shared above we can only see that you are adding the data to the Db. Can you add more Code ? – Fire-In-D-Hole Mar 27 '19 at 20:38
  • the function works perfectly in display the data, only when the data is updated or if the function runs more than once, the table does not get replaced with new data, but instead new data is being added to it. – Quba Mar 27 '19 at 21:00

2 Answers2

1

you can use setInterval to reload the dataset very few seconds, and check if it was updated.

    // you have some var'data' that stores the current data...

    function check_updated(){
       var databaseRef = firebase.database().ref('Classes/'+x+'/students');
       databaseRef.limitToLast(1).once('value', function(snapshot) {
          // CHECK IF CHANGED - GRAB THE LAST ITEM
          // 'LastValue' should be implemented in your code 
          if (snapshot.val().key != LastValue.key){
                resetTable();
          }

       }
    }

    var reloadingInterval = setInterval(check_updated, 10000);
Dror Hilman
  • 6,837
  • 9
  • 39
  • 56
0

Ok so i have found a solution to this problem, it is not the expected solution as the table has to be manually refreshed in order to display updated data, but it works and there are no duplicates. I have created a function which clears the table. the function is as follows and it is invoked at the beginning of myFunction()

function resetTable(){

var table = document.getElementById("tbl_users_list");

for(var i = table.rows.length - 1; i > 0; i--)
{
    table.deleteRow(i);
}

}

function getData() {

resetTable();

  var tblUsers = document.getElementById('tbl_users_list');
  x = document.getElementById("mySelect").value;
  var databaseRef = firebase.database().ref('Classes/'+x+'/students');
  var rowIndex = 1;

  databaseRef.once('value', function(snapshot) {

  snapshot.forEach(function(childSnapshot) {

  var childKey = childSnapshot.key;
  var childData = childSnapshot.val();


  var row = tblUsers.insertRow(rowIndex);
  var cellId = row.insertCell(0);
  var cellName = row.insertCell(1);
  var cellPresent = row.insertCell(2);


  cellId.appendChild(document.createTextNode(childKey));
  cellName.appendChild(document.createTextNode(childData.name));
  cellPresent.appendChild(document.createTextNode(childData.present));

  rowIndex = rowIndex + 1;      


  });
});

}

Please if you know the right way of doing it, answer the question please.

Quba
  • 11
  • 6
  • As Andrew mentioned your goal is to fetch the latest data to remove the existing data you can run a function to delete the existing data before forEach method i see thats what you have done . – Fire-In-D-Hole Mar 28 '19 at 06:54
  • yes only problem is that now the data is not realtime, the table has to be refreshed as every-time i manually update the data in the firebase console i still get a duplicate. – Quba Mar 28 '19 at 16:40
  • Can you edit your question with all HTML, JS files added that way I can figure out how your code is and help you out. – Fire-In-D-Hole Mar 28 '19 at 18:44
  • as per your request, there is not much, literally a select and a table. – Quba Mar 28 '19 at 20:00