New component under a PaginatedMessage

Hello ! I want to add a new component under my PagniatedMessage. This PaginatedMessage is a list embed that represents entities of a model. The user is invited to chose a row to edit via a select menu under the embed. The select menu is successfully added when the embed shows but disapear when I change page. I would like to know how to make my dropdown list refresh on every page change, is there a listener or something like that that can handle this? Here is the code of the listEntities method :
protected async listEntities(interaction: CommandInteraction<CacheType>, page: number) {
try {
//creting a modelInstance with the redis basemodel
const ModelInstance = await this.Model;
//get all the entities (rows) in the table
const entities = await ModelInstance.getAll();

if (entities.length === 0) {
await interaction.reply({ content: `Aucune ${this.entityName} n'est enregistrée.`, ephemeral: true });
return;
}

const itemsPerPage = 10; // maximum items per page
const uniqueId = Date.now(); // Unique ID variable

const selectMenu = new StringSelectMenuBuilder() // Select menu for chosing an entity
.setCustomId(`select_entity_${uniqueId}`)
.setPlaceholder('Sélectionner un élément pour plus d\'options')
.addOptions(entities.map(entity => ({
label: entity.name || entity.label,
value: entity.id
})));

const selectRow = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(selectMenu);

const paginatedMessage = new PaginatedMessage(); //The paginated message

for (let i = 0; i < entities.length; i += itemsPerPage) { //Insertion
const paginatedItems = entities.slice(i, i + itemsPerPage);
const description = paginatedItems
.map((entity, index) => `${i + index + 1}. ${entity.name || entity.label}`)
.join('\n');

paginatedMessage.addPage({
embeds: [
new EmbedBuilder()
.setTitle(`Liste des ${this.entityName}s (Page ${(i / itemsPerPage) + 1})`)
.setColor('#0099ff')
.setDescription(description)
]
});
}

await paginatedMessage.run(interaction);

// Fetch current components (buttons) and add selectRow without replacing them
const message = await interaction.fetchReply();
const currentComponents = message.components ? [...message.components] : [];
currentComponents.push(selectRow); // Add the select menu to existing components

await interaction.editReply({
components: currentComponents
});

const selectCollector = interaction.channel?.createMessageComponentCollector({
componentType: ComponentType.StringSelect,
time: 60000,
filter: (i) => i.customId === `select_entity_${uniqueId}` && i.user.id === interaction.user.id,
});

selectCollector?.on('collect', async (i) => {
if (i.user.id !== interaction.user.id) {
await i.reply({ content: 'Vous ne pouvez pas utiliser cette sélection.', ephemeral: true });
return;
}

await this.showEntityDetails(i, i.values[0]);
});

} catch (error) {
console.error(`Erreur lors de la récupération des ${this.entityName}s:`, error);
await interaction.reply({ content: `Impossible de lister les ${this.entityName}s.`, ephemeral: true });
}
}
protected async listEntities(interaction: CommandInteraction<CacheType>, page: number) {
try {
//creting a modelInstance with the redis basemodel
const ModelInstance = await this.Model;
//get all the entities (rows) in the table
const entities = await ModelInstance.getAll();

if (entities.length === 0) {
await interaction.reply({ content: `Aucune ${this.entityName} n'est enregistrée.`, ephemeral: true });
return;
}

const itemsPerPage = 10; // maximum items per page
const uniqueId = Date.now(); // Unique ID variable

const selectMenu = new StringSelectMenuBuilder() // Select menu for chosing an entity
.setCustomId(`select_entity_${uniqueId}`)
.setPlaceholder('Sélectionner un élément pour plus d\'options')
.addOptions(entities.map(entity => ({
label: entity.name || entity.label,
value: entity.id
})));

const selectRow = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(selectMenu);

const paginatedMessage = new PaginatedMessage(); //The paginated message

for (let i = 0; i < entities.length; i += itemsPerPage) { //Insertion
const paginatedItems = entities.slice(i, i + itemsPerPage);
const description = paginatedItems
.map((entity, index) => `${i + index + 1}. ${entity.name || entity.label}`)
.join('\n');

paginatedMessage.addPage({
embeds: [
new EmbedBuilder()
.setTitle(`Liste des ${this.entityName}s (Page ${(i / itemsPerPage) + 1})`)
.setColor('#0099ff')
.setDescription(description)
]
});
}

await paginatedMessage.run(interaction);

// Fetch current components (buttons) and add selectRow without replacing them
const message = await interaction.fetchReply();
const currentComponents = message.components ? [...message.components] : [];
currentComponents.push(selectRow); // Add the select menu to existing components

await interaction.editReply({
components: currentComponents
});

const selectCollector = interaction.channel?.createMessageComponentCollector({
componentType: ComponentType.StringSelect,
time: 60000,
filter: (i) => i.customId === `select_entity_${uniqueId}` && i.user.id === interaction.user.id,
});

selectCollector?.on('collect', async (i) => {
if (i.user.id !== interaction.user.id) {
await i.reply({ content: 'Vous ne pouvez pas utiliser cette sélection.', ephemeral: true });
return;
}

await this.showEntityDetails(i, i.values[0]);
});

} catch (error) {
console.error(`Erreur lors de la récupération des ${this.entityName}s:`, error);
await interaction.reply({ content: `Impossible de lister les ${this.entityName}s.`, ephemeral: true });
}
}
Thank you for your help ! Have a great day !
No description
Solution:
I think you want to use actions
Jump to solution
5 Replies
Wenwen
WenwenOP2mo ago
Does anyone have any idea how to do this please?
Solution
secre
secre2mo ago
I think you want to use actions
secre
secre2mo ago
tbh this thing is very flexible :okie:
Wenwen
WenwenOP2mo ago
Thx I check this tomorrow ! It works ! Thank you !!
secre
secre2mo ago
:okie:
Want results from more Discord servers?
Add your server