Hello.
I want to make a leaderboard command with quick.db.
How can I do it?
Hello.
I want to make a leaderboard command with quick.db.
How can I do it?
What kind of leaderboard do you want to make?
Are you storing data already? Are you having problems storing data or sorting it?
My code is already storing data. I have problems with sorting it and displaying only 10 per page.
The leaderboard I want to make is:
There is no method in quick.db
to sort the data.
But maybe you can use db.all()
which give you an array.
Then array.sort(...)
Finally a loop to make the āpaginationā.
Tell us if you have a problem with the code. Maybe you can share how is the structure of your db.all()
result array
Well, Iāve already saw the quick.db docs, ADN thereās a say to sort ALL the users. And I already tryed many times to use the loops and pagination. Iām asking here because I really donāt know how to do it.
I find a way to sort the data with an older version. In the new one there is no function to sort it, so you have to use array.sort()
OLD VERSION [6.3.2]
package.json
...
"dependencies": {
...,
"quick.db": "6.3.2"
}
...
leaderboard.js
async function getLeaderboard (page, per_page) {
// Get all data sorted. Replace string
const resp = await db.startsWith('string', {sort: '.data'});
// Pagination
var page = page || 1,
per_page = per_page || 10,
offset = (page - 1) * per_page,
paginatedItems = resp.slice(offset).slice(0, per_page),
total_pages = Math.ceil(resp.length / per_page);
let end = {
page: page,
per_page: per_page,
pre_page: page - 1 ? page - 1 : null,
next_page: (total_pages > page) ? page + 1 : null,
total: resp.length,
total_pages: total_pages,
data: paginatedItems
};
// RESULT
return end;
}
NEW VERSION [7.0.0-b22]
If you use the updated version of quick.db you have to sort manually your data
leaderboard.js
function getLeaderboard (page, per_page) {
// Get all data not sorted
const resp = db.all();
// Sort from higher to lower
resp.sort((a, b) => (a.data < b.data) ? 1 : -1);
/* Pagination: copy the code from last example */
// RESULT
return end;
}
The return data for both examples is something like this:
getLeaderboard(1, 10);
{ page: 1,
per_page: 10,
pre_page: null,
next_page: 2,
total: 200,
total_pages: 20,
data:
[ { ID: 'Nick[83]', data: 9972 },
{ ID: 'Nick[182]', data: 9907 },
{ ID: 'Nick[106]', data: 9899 },
{ ID: 'Nick[173]', data: 9895 },
{ ID: 'Nick[116]', data: 9886 },
{ ID: 'Nick[142]', data: 9858 },
{ ID: 'Nick[148]', data: 9831 },
{ ID: 'Nick[114]', data: 9803 },
{ ID: 'Nick[153]', data: 9769 },
{ ID: 'Nick[189]', data: 9548 } ] }
OK. It seems to work. But now I have the problem with sending an embed like this:
Leaderboard
Page: 1+++
^^^^ Here I want to show for each user: āUsername: usercoins coinsā
Edit: And I want to show only the coins. I use the db to XP, coins, and others.
// Pagination
var page = page || 1,
per_page = per_page || 10,
offset = (page - 1) * per_page,
paginatedItems = resp.slice(offset).slice(0, per_page),
total_pages = Math.ceil(resp.length / per_page);
// Leaderboard Message -> Make your message as you want.
var leaderboardMessage;
for (var i in paginatedItems) {
leaderboardMessage += `${paginatedItems[i].ID} | Data: ${paginatedItems[i].data} \n`;
}
let end = {
page: page,
per_page: per_page,
pre_page: page - 1 ? page - 1 : null,
next_page: (total_pages > page) ? page + 1 : null,
total: resp.length,
total_pages: total_pages,
data: paginatedItems,
message: leaderboardMessage
};
// RESULT
return end;
OK. So, all I have to do for the message is put leaderboardMessage in the description field, right?
And can I replace db.all() by db.all(ācoinsā)?
I donāt know about db.all('coins')
But yeah. You should know, with all the information I gave to you, how you want to make your own command
OK. I used the old version, and it works fine, but it isnāt sending the message.
Hereās my code: https://pastebin.com/Ps9i9SuW
Hey there, @TheBigerGamer!
The above post is not āat allā related to Discord.js. Please refrain from posting such questions in wrong categories.
I only asked because Iām using it in my discord.js bot.
Line 10
const resp = await db.startsWith('string', {sort: '.data'});
You should change āstringā for what your query to the database.
The db.startsWith(...)
function is going to searh all the keys of your db wich starts with the first argument. In this example start with āstringā
Take out the return end;
at your line 38. This is where your code is stop reading so it doesnāt send message.
You can add return message.channel.send(topembed)
in the 46 line
Itās a range error
Your RichEmbed is exceeding the limit, the maximum limit is 256 characters for a RichEmbed field.
EDIT: You can split them up into two embed if it exceeds the limit
Well, I finally changed the code, and now it shows the leaderboard, but I have THIS:
The code is this:
const db = require('quick.db');
exports.run = async (bot, message, args) => {
async function getLeaderboard (page, per_page) {
// Get all data not sorted
const resp = await db.startsWith('moons_', {sort: '.data'});
// Pagination
var page = page || 1,
per_page = per_page || 5,
offset = (page - 1) * per_page,
paginatedItems = resp.slice(offset).slice(0, per_page),
total_pages = Math.ceil(resp.length / per_page);
let id = resp.slice('moons_')
console.log(id)
// Leaderboard Message -> Make your message as you want.
var leaderboardMessage;
for (var i in paginatedItems) {
leaderboardMessage += `${paginatedItems[i].ID} | Moons: ${paginatedItems[i].data} \n`;
}
let end = {
page: page,
per_page: per_page,
pre_page: page - 1 ? page - 1 : null,
next_page: (total_pages > page) ? page + 1 : null,
total: resp.length,
total_pages: total_pages,
data: paginatedItems,
message: leaderboardMessage
};
// RESULT
console.log(leaderboardMessage)
const topembed = new Discord.RichEmbed()
.setColor(16777215)
.setAuthor('Top de Moons')
.setDescription('Top de Moons do S1mple', `PƔgina: ${page}`)
.addField(leaderboardMessage, `Top 5`)
.setFooter(`PƔgina: ${page} | Por pƔgina: ${per_page}`)
return message.channel.send(topembed)
}
getLeaderboard (1, 5)
}
module.exports.command = {
name: 'topmoons',
aliases: ['leaderboard', 'top'],
description: 'Veja os mais ricos do servidor!',
category: "Economia",
usage: 'topmoons',
enabled: false
}
You see paginatedItems[i].ID
is returning undefined for the first element of the array, from what I could gather.
I already saw that. But whatās the solution?