Isolating interactions on Select Menu’s

Hello friends! Looking for some guidance and did not get too far online Setup: I have a Select Menu and a Button in a global channel that users can interact with When the user selects an option, it is stored to a variable. The button is used to “confirm” the selection (UX 🤷‍♂️) Code for posting the embed is in our Bot OnReady event Code for handling is in a separate InteractionCreate event handler Issue: All works except when another user interacts with the Select Menu, it effects the choice for a different user when they click confirm. My assumptions: I am trying to use a Component Collector with filter, however, adding this to the interactioncreate seems to only create a collector after the user has already interacted Or, does it make sense to create a map with discordID: selected option and look for this on button click? I can post code and screenshots if needed for better context. TIA 👌
3 Replies
d.js toolkit
d.js toolkit12mo ago
• What's your exact discord.js npm list discord.js and node node -v version? • Post the full error stack trace, not just the top part! • Show your code! • Explain what exactly your issue is. • Not a discord.js issue? Check out #useful-servers.
treble/luna
treble/luna12mo ago
You have to attach it to the message that contains the components
CRY$TAL
CRY$TAL12mo ago
Does that also include each reply with new components? For anyone who might stumble on this thread, I managed to get this working as below (now, other use interactions do not disrupt selections). Note: I will leave this open temporarily in-case there is some bad practice here or something that could be better handled: Summary: 1. I have nested component collectors for each reply with new components 2. Instead of saving selected value to a global variable on Select Menu click, I am accessing the map of the collector to get the Select Menu selection embedHandler.js
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {


if(interaction.type == InteractionType.MessageComponent) {
if(interaction.customId == 'view-shop') {

const packs = await Packs.find();
const select = new StringSelectMenuBuilder()
.setCustomId('cards')
.setPlaceholder('Select a Card Pack!')
.setDisabled(false)
packs.forEach(item =>
select.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel(item.packName)
.setDescription(`A ${item.packTier} Card Pack. Price: ${item.packCost} Gold`)
.setEmoji('🃏')
.setValue(item.packId),
)
);

const row1 = new ActionRowBuilder()
.addComponents(select);

await interaction.reply({components: [row1], ephemeral: true});
const response = await interaction.fetchReply();

const filters = i => (i.user.id === interaction.user.id);
const selection = await response.createMessageComponentCollector({filter: filters, componentType: ComponentType.StringSelect});

selection.on('collect', async i => {
await interaction.deleteReply();
await i.reply({content: `Confirm your purchase for ${i.values[0]}?`, components: [row2], ephemeral: true});
const response2 = await i.fetchReply();
const confirmButt = await response2.createMessageComponentCollector({filter: filters, componentType: ComponentType.Button});

confirmButt.on('collect', async i => {
if (i.customId === 'confirm-shop-buy') {
const map = selection.collected.first();
//console.log(map.values[0], "SELECTION");
const bResponse = await userAddPack(map.values[0], i.member.id);
await i.followUp(bResponse);
}
})
});


}
}

},
};
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {


if(interaction.type == InteractionType.MessageComponent) {
if(interaction.customId == 'view-shop') {

const packs = await Packs.find();
const select = new StringSelectMenuBuilder()
.setCustomId('cards')
.setPlaceholder('Select a Card Pack!')
.setDisabled(false)
packs.forEach(item =>
select.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel(item.packName)
.setDescription(`A ${item.packTier} Card Pack. Price: ${item.packCost} Gold`)
.setEmoji('🃏')
.setValue(item.packId),
)
);

const row1 = new ActionRowBuilder()
.addComponents(select);

await interaction.reply({components: [row1], ephemeral: true});
const response = await interaction.fetchReply();

const filters = i => (i.user.id === interaction.user.id);
const selection = await response.createMessageComponentCollector({filter: filters, componentType: ComponentType.StringSelect});

selection.on('collect', async i => {
await interaction.deleteReply();
await i.reply({content: `Confirm your purchase for ${i.values[0]}?`, components: [row2], ephemeral: true});
const response2 = await i.fetchReply();
const confirmButt = await response2.createMessageComponentCollector({filter: filters, componentType: ComponentType.Button});

confirmButt.on('collect', async i => {
if (i.customId === 'confirm-shop-buy') {
const map = selection.collected.first();
//console.log(map.values[0], "SELECTION");
const bResponse = await userAddPack(map.values[0], i.member.id);
await i.followUp(bResponse);
}
})
});


}
}

},
};