Can't give multiple roles with dropdown roles

Viewed 533

I'm trying to make a dropdown role system in discord.js version 12 and whenever I select more than one role it only gives me the first one I add.

Here is my code:

client.on('clickMenu', async menu => {

        if (menu.values[0] == "quote_pings") {
          if (menu.clicker.member.roles.cache.has("809011668465745940")) {
            await menu.clicker.member.roles.remove("809011668465745940")
            return menu.reply.send("I have removed you from the quote pings role.", true)
          } else if (!menu.clicker.member.roles.cache.has("809011668465745940")){
            await menu.clicker.member.roles.add("809011668465745940")
            return menu.reply.send("I have given you the quote pings role!", true)
          }
        } else if (menu.values[0] == "economy_pings") {
          if (menu.clicker.member.roles.cache.has("809354393413222431")) {
            await menu.clicker.member.roles.remove("809354393413222431")
            return menu.reply.send("I have removed you from the economy pings role.", true)
          } else if (!menu.clicker.member.roles.cache.has("809354393413222431")){
            await menu.clicker.member.roles.add("809354393413222431")
            return menu.reply.send("I have given you the economy pings role!", true)
          }
        }  else if (menu.values[0] == "server_pings") {
          if (menu.clicker.member.roles.cache.has("772763475973242900")) {
            await menu.clicker.member.roles.remove("772763475973242900")
            return menu.reply.send("I have removed you from the economy pings role.", true)
          } else if (!menu.clicker.member.roles.cache.has("772763475973242900")){
            await menu.clicker.member.roles.add("772763475973242900")
            return menu.reply.send("I have given you the economy pings role!", true)
          }
        }   else if (menu.values[0] == "event_pings") {
          if (menu.clicker.member.roles.cache.has("828575560137572402")) {
            await menu.clicker.member.roles.remove("828575560137572402")
            return menu.reply.send("I have removed you from the event pings role.", true)
          } else if (!menu.clicker.member.roles.cache.has("828575560137572402")){
            await menu.clicker.member.roles.add("828575560137572402")
            return menu.reply.send("I have given you the event pings role!", true)
          } 
        } else if (menu.values[0] == "movie_pings") {
          if (menu.clicker.member.roles.cache.has("828575746845835305")) {
            await menu.clicker.member.roles.remove("828575746845835305")
            return menu.reply.send("I have removed you from the event pings role.", true)
          } else if (!menu.clicker.member.roles.cache.has("828575746845835305")){
            await menu.clicker.member.roles.add("828575746845835305")
            return menu.reply.send("I have given you the event pings role!", true)
          }  
        } else if (menu.values[0] == "chat_pings") {
          if (menu.clicker.member.roles.cache.has("872241962588201031")) {
            await menu.clicker.member.roles.remove("872241962588201031")
            return menu.reply.send("I have removed you from the chat revive pings role.", true)
          } else if (!menu.clicker.member.roles.cache.has("872241962588201031")){
            await menu.clicker.member.roles.add("872241962588201031")
            return menu.reply.send("I have given you the chat revive pings role!", true)
          }  
        }
      })

Whenever I get all the roles, I only get one role.

2 Answers

In your code, you are only comparing the first item of menu.values, by using menu.values[0]. If you want to add/remove all roles, you will need to use a loop of some kind:

client.on("clickMenu", async (menu) => {
  const { values } = menu;
  // Run through all values selected
  for (const value of values) {
    // Do different actions based on the current value
    // if/else if can also be used instead of a switch statement
    switch (value) {
      case "quote_pings": {
        if (menu.clicker.member.roles.cache.has("809011668465745940")) {
          await menu.clicker.member.roles.remove("809011668465745940");
          menu.reply.send("I have removed you from the quote pings role.", true);
        } else if (!menu.clicker.member.roles.cache.has("809011668465745940")){
          await menu.clicker.member.roles.add("809011668465745940");
          menu.reply.send("I have given you the quote pings role!", true);
        }
        break;
      }
      case "economy_pings": {
        if (menu.clicker.member.roles.cache.has("809354393413222431")) {
          await menu.clicker.member.roles.remove("809354393413222431");
          menu.reply.send("I have removed you from the economy pings role.", true);
        } else if (!menu.clicker.member.roles.cache.has("809354393413222431")){
          await menu.clicker.member.roles.add("809354393413222431");
          menu.reply.send("I have given you the economy pings role!", true);
        }
        break;
      }
      /**
       * etc...
       */
    }
  }
});

The problem is that you're only checking the first element of the menu.values (menu.values[0]). It's perfectly fine if you only allow a single one but won't work if you select more than one role. To solve this you can iterate over all the selected values.

You could also simplify your code by creating a roles object where the keys are the menu values.

client.on('clickMenu', async menu => {
  let roles = {
    quote_pings: {
      id: '809011668465745940',
      name: 'quote pings',
    },
    economy_pings: {
      id: '809354393413222431',
      name: 'economy pings',
    },
    server_pings: {
      id: '772763475973242900',
      name: 'server pings',
    },
    event_pings: {
      id: '828575560137572402',
      name: 'event pings',
    },
    movie_pings: {
      id: '828575746845835305',
      name: 'movie pings',
    },
    chat_pings: {
      id: '872241962588201031',
      name: 'chat revive pings',
    },
  }

  for (let value of menu.values) {
    let role = roles[value]
    if (!role) continue

    if (menu.clicker.member.roles.cache.has(role.id)) {
      await menu.clicker.member.roles.remove(role.id)
      menu.reply.send(`I have removed you from the ${role.name} role.`, true)
    } else {
      await menu.clicker.member.roles.add(role.id)
      menu.reply.send(`I have given you the ${role.name} role!`, true)
    }
  }
})
Related