I was on a week or two ago asking about data in Firebase. Thanks to the help on this forum and a lot of google, I was able to get my database set up and I am now retrieving data from the Firebase database.
My new question is, how do I retrieve this data and then use the data to build a leaderboard. Everytime a score is added/updated, I want to loop through this data, find everyone who has a score (the count variable) and then print out the username and score. I have tried a number of solutions and currently the best I can do is adding every user with a score to the div everytime a score is added/updated. But I only want one entry per person and I want the entry to update each time the score changes.
Here is what my code looks like so far:
<div class="leaderboard">
<p>Leaderboard</p>
<ul id="leaderboard">
</ul>
</div>
<script>
let leadsRef = database.ref('users');
let leaderboard = document.querySelector('#leaderboard');
let array = [];
// I get the data using this function
leadsRef.on('value', function (data) {
var childData = childSnapshot.val();
// childData is now a bunch of typeof objects that looks like this:
// { count: 0, username: 'John' }
// now, I try to loop through each of these objects and add them to the leaderboard
if (childData.count >= 0) {
let li = document.createElement('li');
let text = document.createTextNode(childData.username + ' has a score of ' + childData.count);
li.appendChild(text);
leaderboard.appendChild(li);
}
// this leads to every user and score being printed over and over again whenever the count increases for a user
// so I tried adding leaderboard.innerHTML = ''; before I create the li, and that doesn't work either
}
</script>
So, I get really confused by this, but I don’t think that childData is an array. I think it just returns an object for each? When I console.log(typeof childData) it returns object and when I console.log(childData) it returns {count: whatever, username: whatever}.
Does that help at all?
There also could be two or more objects with the same username, although in the very limited demonstration I’m doing, there will not be.
Thank you so much for your help. I have been able to implement this and it is working better than before. I think I’m not understanding the part about how to update the data. Here is the code that I’ve wrote based on your response. The current result is: when the player first starts the game, the leaderboard shows all of the people who’ve scored in the game before, which is what I want. But, when the new player scores, it just adds all of the players and scores over and over again.
const userCounts = {};
leadsRef.on('value', function (data) {
data.forEach(function (childSnapshot, index) {
var childData = childSnapshot.val();
if (childData.count > 0) {
if (userCounts.hasOwnProperty(childData.username)) {
//
} else {
userCounts[childData.username] = childData.count;
}
}
}); // this is the end of the foreach
Object.keys(userCounts).forEach(function(key) {
console.log(key, userCounts[key]);
let li = document.createElement('li');
li.id = key.toLowerCase();
li.innerHTML = key + ' scored ' + userCounts[key];
leaderboard.appendChild(li);
});
});
leadsRef.on('value', function (data) {
data.forEach(function (childSnapshot, index) {
var childData = childSnapshot.val();
if (childData.count > 0) {
if (userCounts.hasOwnProperty(childData.username)) {
newId = childData.username.toLowerCase();
let userCountHolder = document.getElementById(newId);
userCountHolder.innerHTML = childData.count;
console.log(userCountHolder);
} else {
userCounts[childData.username] = childData.count;
console.log(userCounts);
let li = document.createElement('li');
newId = childData.username.toLowerCase();
li.innerHTML = childData.username + ' scored ' + '<span id="' + newId + '">' + childData.count + '</span>';
leaderboard.appendChild(li);
}
}
}); // this is the end of the foreach
});
It works right now but the method that you’ve suggested seems cleaner.
Thank you so much for your help, I really appreciate it!
EDIT: I don’t know if this is useful at all, but for whatever reason, the index parameter in the forEach always returns undefined, when I would normally expect it to return the index number.