js and quickmongo for a leaderboard command but it shows the named of all the users in the database and I want it to show names of users who are in the guild only. Any help is highly appreciated 🙏. I tried filtering it too… My current code
const Discord = require('discord.js') module.exports.run = async (bot, message, args, db) => { let eco = await db.fetch(`eco_${message.author.id}`) if(eco !== 'START') return message.reply(`you/They have not yet started your economy journey.n**Start it now by typing `gg ecostart`**`) const ic = '<:mythicalcoin:842637611150606356>' let data = await db.startsWith("mon_"); message.guild.members.fetch().then((m) => { m.forEach(user => { data.filter(i => i.ID.endsWith(user.id)) }) }).catch((e) => { console.log(e) }) let money = data.sort((a, b) => (b.data-a.data)) money.length = 20; var finalLb = ""; for (var i in money) { finalLb += `${money.indexOf(money[i])+1}.${(await message.guild.members.fetch(money[i].ID.split('_')[1])).username ? (await message.guild.members.fetch(money[i].ID.split('_')[1])).username : "Unknown User#0000"} || 'n' : ${ic} `${parseInt(JSON.stringify(money[i].data)).toLocaleString()}`n`; } const embed = new Discord.MessageEmbed() .setAuthor(`Leaderboard`, message.guild.iconURL()) .setColor("PURPLE") .setDescription(finalLb) .setFooter(bot.user.tag, bot.user.displayAvatarURL()) .setTimestamp() message.channel.send(embed); } module.exports.help = { name:"rich", aliases: ["lb", "leaderboard"] }
Help me please
Advertisement
Answer
Array#filter()
doesn’t modify arrays in place, it only returns the filtered result. For example:
const arr = [1, 2, 3]; const filteredArr = arr.filter((num) => num !== 2); // this still shows all the numbers, // because arr.filter() didn't modify the // original array console.log(arr); // [1, 2, 3]; // however, it did *return* a filtered // array console.log(filteredArr); // [1, 3];
So, you’ll simply need to reassign data
to the filtered array.
let data = await db.startsWith('mon_'); message.guild.members .fetch() .then((m) => { m.forEach((user) => { data = data.filter((i) => i.ID.endsWith(user.id)); }); }) .catch((e) => { console.log(e); });
However, this still won’t work. This is because you’re filtering the array within a callback. The whole purpose of a callback is to trigger after a promise is resolved, so by the time you’re able to filter the array, all of the other code will have already been executed.
Understanding promises:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
- https://discordjs.guide/additional-info/async-await.html
- https://javascript.info/async-await
If you choose to use async/await
, you can refactor your code like so:
let data = await db.startsWith('mon_'); try { const m = await message.guild.members.fetch(); m.forEach((user) => { data = data.filter((i) => i.ID.endsWith(user.id)); }); } catch (e) { console.log(e); }
While working, this solution is not optimal, since you have to filter and reassign data
for every single member. Instead, you should try to only do it once. You can achieve this using Array#some()
const m = await message.guild.members.fetch(); data = data.filter((i) => m.some((user) => i.ID.endsWith(user.id)));