How to show roles of user discord.js / userinfo command

Viewed 42831

I'm trying to make a userinfo command, and I'm currently stuck on showing roles of the user.

Here is my code:

const Discord = module.require('discord.js');
const moment = require('moment');

module.exports.run = async (bot, message, args) => {

    let user = message.mentions.users.first() || message.author;
    const joinDiscord = moment(user.createdAt).format('llll');
    const joinServer = moment(user.joinedAt).format('llll');
    let embed = new Discord.RichEmbed()
        .setAuthor(user.username + '#' + user.discriminator, user.displayAvatarURL)
        .setDescription(`${user}`)
        .setColor(`RANDOM`)
        .setThumbnail(`${user.displayAvatarURL}`)
        .addField('Joined at:', `${moment.utc(user.joinedAt).format('dddd, MMMM Do YYYY, HH:mm:ss')}`, true)
        .addField('Status:', user.presence.status, true)
        .addField('Roles:', user.roles.map(r => `${r}`).join(' | '), true)
        .setFooter(`ID: ${user.id}`)
        .setTimestamp();

    message.channel.send({ embed: embed });
    return;
}

module.exports.help = {
    name: 'userinfo'
}

I'm getting this error TypeError: Cannot read property 'map' of undefined and I don't know how to fix it?

6 Answers

User.roles is undefined because that property doesn't exist: try using GuildMember.roles instead:

let member = message.mentions.members.first() || message.member,
  user = member.user;

let embed = new Discord.RichEmbed()
  // ... all the other stuff ...
  .addField('Roles:', member.roles.map(r => `${r}`).join(' | '), true)

The other properties will still use user, but .roles will be related to the GuildMember.

try adding this .addField("Roles:", member.roles.map(roles =>${roles}).join(', '), true)

My whole code for this is

let user;
if (message.mentions.users.first()) {
    user = message.mentions.users.first();
} else {
    user = message.`enter code here`author;
}

const member = message.guild.member(user);

const embed = new Discord.RichEmbed()
    .setColor("RANDOM")
    .setThumbnail(message.author.avatarURL)
    .addField(`${user.tag}`, `${user}`, true)
    .addField("ID:", `${user.id}`, true)
    .addField("Nickname:", `${member.nickname !== null ? `${member.nickname}` : 'None'}`, true)
    .addField("Status:", `${user.presence.status}`, true)
    .addField("In Server", message.guild.name, true)
    .addField("Game:", `${user.presence.game ? user.presence.game.name : 'None'}`, true)
    .addField("Bot:", `${user.bot}`, true)
    .addField("Joined The Server On:", `${moment.utc(member.joinedAt).format("dddd, MMMM Do YYYY")}`, true)
    .addField("Account Created On:", `${moment.utc(user.createdAt).format("dddd, MMMM Do YYYY")}`, true) 
    .addField("Roles:", member.roles.map(roles => `${roles}`).join(', '), true)
    .setFooter(`Replying to ${message.author.username}#${message.author.discriminator}`)
message.channel.send({embed});

TypeError: Cannot read property 'map' of undefined - this means that somewhere in your code happening a situation of execution .map function of undefined variable.

You have only one map. Here:

   .addField('Roles:', user.roles.map(r => `${r}`).join(' | '), true)
                               // ^^^

This line trows this error, so this means that user.roles is undefined.

Try to:

let user = message.mentions.users.first() || message.author;
console.log(user.roles); // it is undefined

Propably user.roles is undefined.

If it's ok that user has no roles, you can replace:

.addField('Roles:', user.roles.map(r => `${r}`).join(' | '), true)

with:

.addField('Roles:', user.roles ? user.roles.map(r => `${r}`).join(' | ') : "", true)

This will set empty string in case when there's no roles property in user object.

Another option is to set user.roles to empty array if it doesn't exist (or do something else in this if, i.e. throw error):

let user = /* get user*/
if (!user.roles){
    user.roles = [];
}

For roles i also suggest you to remove the @everyone role

Here are an example

message.member.roles.cache.map(r => r.name)

// ["Mod","Member","Staff","Owner","@everyone"]
// If you don't want the everyone role use :

message.member.roles.cachemap(r => r.name).slice(0,-1).

// ["Mod","Member","Staff","Owner"]

So the roles field would be :

.addField("Roles", member.roles.cache.map(r => '`'+r.name+'`').join(' - '), true)

this is working 100% for discord.js 12.x

 <@&${message.guild.member(message.author)._roles.join('> <@&')}>
Related