#
Collections
In this page we will explore Collections, and how to use them to grab data from various part of the API.
A Collection is a utility class that stores data. Collections are the Javascript Map() data structure with additional utility methods. This is used throughout discord.js rather than Arrays for anything that has an ID, for significantly improved performance and ease-of-use.
Examples of Collections include:
client.users.cache
,client.guilds.cache
,client.channels.cache
guild.channels.cache
,guild.members.cache
- message logs (in the callback of
messages.fetch()
) client.emojis.cache
#
Getting by ID
Very simply, to get anything by ID you can use Collection.get(id)
. For instance, getting a channel can be client.channels.cache.get("81385020756865024")
. Getting a user is also trivial: client.users.cache.get("139412744439988224")
#
Finding by key
If you don't have the ID but only some other property, you may use find()
to search by property:
let guild = client.guilds.cache.find(guild => guild.name === "discord.js - imagine a bot");
The first result that returns true
within the function, will be returned. The generic idea of this is:
let result = <Collection>.find(item => item.property === "a value")
You can also be looking at other data, properties not a the top level, etc. Your imagination is the limit.
Want a great example? Here's getting the first role that matches one of 4 role names:
const acceptedRoles = ["Mod", "Moderator", "Staff", "Mod Staff"];
const modRole = member.roles.cache.find(role => acceptedRoles.includes(role.name));
if (!modRole) return "No role found";
Don't need to return the actual role? .some()
might be what you need. It's faster than find, but will only return a boolean true/false if it finds something:
const hasModRole = member.roles.cache.some(role => acceptedRoles.includes(role.name));
// hasModRole is boolean.
#
Custom filtering
Collections also have a custom way to filter their content with an anonymous function:
let large_guilds = client.guilds.cache.filter(g => g.memberCount > 100);
filter()
returns a new collection containing only items where the filter returned true
, in this case guilds with more than 100 members.
#
Mapping Fields
One great thing you can do with a collection is to grab specific data from it with map()
, which is useful when listing stuff. <Collection>.map()
takes a function which returns a string. Its result is an array of all the strings returned by each item. Here's an example: let's get a complete list of all the guilds a bot is in, by name:
const guildNames = client.guilds.cache.map(g => g.name).join("\n")
Since .join()
is an array method, which links all entries together, we get a nice list of all guilds, with a line return between each. Neat!
We can also get a most custom string. Let's pretend the user.tag
property doesn't exist, and we wanted to get all the user#discriminator in our bot. Here's how we'd do it (using awesome template literals):
const tags = client.users.cache.map(u => `${u.username}#${u.discriminator}`).join(", ");
#
Combining and Chaining
In a lot of cases you can definitely chain methods together for really clean code. For instance, this is a comma-delimited list of all the small guilds in a bot:
const smallGuilds = client.guilds.cache.filter(g => g.memberCount < 10).map(g => g.name).join("\n");
#
More Data!
To see all of the Discord.js Collection Methods, please refer to the docs. Since Collection extends Map(), you will also need to refer to this awesome mdn page which describe the native methods - most notably .forEach()
, .has()
, etc.