Euan
Euan

Reputation: 23

How to create a table that updates correctly when I add values to a firebase realtime database?

The current solution that I have displays the data correctly when I load the screen, but when I add a value via the input from my HTML page it duplicates the table values and includes the new value. When I refresh the page there aren't any duplicates anymore. I'm not too sure how to approach another solution. Is there a way to create a new table that replaces the old one every time something is added to the database? Or is there a way to add to the old table somehow?

This is the table when I first load the page

This is the table after I added the value

Here is my html code for the table

<table class="table table-dark">
  <thead>
    <tr>
      <th scope="col">Date</th>
      <th scope="col">Shots Attempted</th>
      <th scope="col">Shots Made</th>
      <th scope="col">Percentage</th>
    </tr>
  </thead>
  <tbody id="table-body">

  </tbody>
</table>

Here is my js that calls the firebase database values and adds them to the table

var query = rootRef.orderByKey();
let table = document.getElementById('table-body');
query.on('value', function(dataSnapshot) {
  dataSnapshot.forEach(function(childSnapshot) {
    const key = childSnapshot.key;
    const childData = childSnapshot.val();
    let table = document.getElementById('table-body');
    const row = `<tr>
                <td>${key}</td>
                <td>${childData.shotsM}</td>
                <td>${childData.shotsA}</td>
                <td>${childData.shotsP}</td>
              </tr>`

    table.innerHTML += row
  })
})  

Upvotes: 2

Views: 62

Answers (1)

Phil
Phil

Reputation: 165059

  1. On value updates, empty the <tbody>
  2. Iterate the new values and add them to the table
var query = rootRef.orderByKey();
let table = document.getElementById('table-body');
const cells = ['shotsM', 'shotsA', 'shotsP']

// just a simple tag creator utility
const createTag = (tagName, textContent, props) =>
  Object.assign(document.createElement(tagName), { textContent }, props)

query.on('value', dataSnapshot => {
  table.innerHTML = '' // empty the <tbody>
  dataSnapshot.forEach(childSnapshot => {
    const key = childSnapshot.key
    const childData = childSnapshot.val()

    // create a new row
    const tr = createTag('tr')
    // create a cell for the "key"
    const keyCell = createTag('td', key)

    // add all the cells to the new row
    tr.append(keyCell, ...cells.map(cell => createTag('td', childData[cell])))

    // add the row to the table
    table.append(tr)
  })
})  

You don't have to use the DOM methods like document.createElement() but I just find it much cleaner than working with strings of HTML.

Upvotes: 1

Related Questions