#Cutting buttons out of the container

74 messages · Page 1 of 1 (latest)

formal viper
#

Hi there

I've a question about the new containers. How can I cut my buttons out of the container after I've clicked the button?

I need all the buttons at the bottom to disappear from this container after I click on the button in the container (there are two buttons for the solution)

shut jettyBOT
deep halo
#

Edit the message with the components without the ActionRow containing those buttons.

formal viper
#

If anything, I'm mean a container like on this screen

formal viper
#

I need to either turn them off or completely refresh the message and cut them out

deep halo
#

That's what I said. "Refreshing" the message means editing it. And you need to provide the components: [...] that you want the message to have afterwards. Which would be the container as it was but omit the actionRow

formal viper
#

K, I'll try it

formal viper
rancid walrus
#

Naturally

formal viper
# rancid walrus Naturally

So I need to send the exact same thing to interaction.message.edit when I sent the last message, only without the buttons?

For ex my code:

            const components = [
                new ContainerBuilder()
                    .setAccentColor(16730955)
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`### Заявка в сообщество #${number}`),
                    )
                    .addSectionComponents(
                        new SectionBuilder()
                            .setThumbnailAccessory(
                                new ThumbnailBuilder()
                                    .setURL(candidateURL)
                            )
                            .addTextDisplayComponents(
                                new TextDisplayBuilder().setContent(`**Пользователь**\n${member}`),
                                new TextDisplayBuilder().setContent(`**Полное имя**\n${fullname}`),
                                new TextDisplayBuilder().setContent(`**День рождения**\n${birthday}`)
                            )
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**О себе**\n${bio}`)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**Департамент**\n${DEPTS_MAP[dept]}`)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**Чем занимается ${DEPTS_MAP[dept]}?**\n${deptDo}`)
                    )
                    .addSeparatorComponents(
                        new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Small).setDivider(true)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**Вы участвуете в другом закрытом сообществе?**\n${anotherRPCommunity ? 'Да' : 'Нет'}`)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**У вас есть исправная гарнитура?**\n${headset ? 'Да' : 'Нет'}`)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**У вас есть лицензионная копия GTA V?**\n${gtaV ? 'Да' : 'Нет'}`)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**Как вы узнали о нас?**\n${discoverMethods[howDidDiscover]}`)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`**Ознакомление с правилами**\n${rulesAgree ? 'Да, я полностью ознакомлен' : 'Ошибка, при получении ответа'}`)
                    )
                    .addSeparatorComponents(
                        new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large).setDivider(true)
                    )
                    .addTextDisplayComponents(
                        new TextDisplayBuilder().setContent(`<@&1233379172181610607>, используйте кнопки ниже для принятия решения:`)
                    )
            ]

            await interaction.message.edit({
                components
            })
harsh raptor
# formal viper So I need to send the exact same thing to interaction.message.edit when I sent t...

try to make the buttons separately, like

const greenButton = new ButtonBuilder().setCustomId('green').setStyle(ButtonStyle.Success).setLabel('Green');
const redButton = new ButtonBuilder().setCustomId('red').setStyle(ButtonStyle.Danger).setLabel('Red');

Then add these buttons in an action row of your container like:

const components = [
  new ContainerBuilder()
    .setAccentColor(16730955)
    // ... rest of your code
    .addActionRowComponents(new ActionRowBuilder().addComponents(greenButton, redButton))
];

This means your container will still hold the same button but now you can access those buttons via the greenButton and redButton constants. Now, to update your message with disabled buttons, just do:

greenButton.setDisabled(true);
redButton.setDisabled(true);
await interaction.message.edit({components});

Or if you insist on removing the buttons instead of disabling them, let me know.

formal viper
#

And could I see an option to remove the buttons? For the future

tepid flame
#

You can use createComponentBuilder ( explained here #1370478227872551032 message ) to turn the component object from a message into a builder for you to manipulate. Then you can use ContainerBuilder#spliceComponents to remove the buttons (or disable them)

rose dustBOT
harsh raptor
tepid flame
#

It's a forum post. It's not cached in your client. Just click it

formal viper
tepid flame
rose dustBOT
#

mdn Array.prototype.splice()
The splice() method of Array instances changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.

fierce moth
#

It behaves just like that ^

formal viper
#

It should looks like this?

let components = interaction.message.components.map(createComponentBuilder)

components.spliceComponents(0, -1)

await interaction.message.edit({
    components,
    flags: MessageFlags.IsComponentsV2
})```
#

I think nope, because It's doesn't work...

#

I'm sooo sorry

fierce moth
formal viper
tepid flame
#

Do you know how to work with arrays?

formal viper
tepid flame
#

Since components there is returned as an array and assuming you only have a single element in it, you can reference the first entry of the array at components[0]

#

Additionally, you also specified a negative amount of components to delete...I don't know what that's supposed to do

formal viper
tepid flame
#

Then instead of starting at index 0 in the splice, start at the last index entry (components[0].length - 1 iirc)

formal viper
#

but:

4|Signal  | TypeError: components.spliceComponents is not a function
4|Signal  |     at Object.execute (/home/bogdan/Signal Bot/events/interactionCreate/systems/application/btn_handler.js:300:24)
4|Signal  |     at process.processTicksAndRejections (node:internal/process/task_queues:103:5)```
tepid flame
#

components[0].spliceComponents(index, 1)

fierce moth
#

As i said it behaves like Array.splice, so (-1, 1) will work

tepid flame
#

(I wasn't sure if that works...thanks NyR)

formal viper
fierce moth
#

Did you try it and see if it worked?

formal viper
#
4|Signal  | Error: Expected a string primitive
4|Signal  |     at _StringValidator.handle (/home/bogdan/Signal Bot/node_modules/@sapphire/shapeshift/dist/cjs/index.cjs:2615:70)
4|Signal  |     at _StringValidator.parse (/home/bogdan/Signal Bot/node_modules/@sapphire/shapeshift/dist/cjs/index.cjs:972:90)
4|Signal  |     at TextDisplayBuilder.toJSON (/home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2074:33)
4|Signal  |     at /home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2237:64
4|Signal  |     at Array.map (<anonymous>)
4|Signal  |     at ContainerBuilder.toJSON (/home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2237:35)
4|Signal  |     at /home/bogdan/Signal Bot/node_modules/discord.js/src/structures/MessagePayload.js:151:46
4|Signal  |     at Array.map (<anonymous>)
4|Signal  |     at MessagePayload.resolveBody (/home/bogdan/Signal Bot/node_modules/discord.js/src/structures/MessagePayload.js:150:49)
4|Signal  |     at GuildMessageManager.edit (/home/bogdan/Signal Bot/node_modules/discord.js/src/managers/MessageManager.js:253:8)
4|Signal  | [2026-01-02 01:14:07] FATAL: An unhandled error was detected: 'Error: Expected a string primitive'```
fierce moth
#

What's your current code? Can you show?

formal viper
deep halo
#

The part the error comes from and you just changed according to this posts topic

formal viper
#

I think it's:

await interaction.message.edit({
    components,
    flags: MessageFlags.IsComponentsV2
})
#

I think that's the most difficult thing I do

formal viper
tepid flame
#

Generally it's not recommended to use .edit() whenever you're working with interactions. They have dedicated endpoints for creating, editing, and deleting interaction messages

rose dustBOT
#

method ButtonInteraction#update() [email protected]
Updates the original message of the component on which the interaction was received on.


// Remove the components from the message
interaction.update({
  content: "A component interaction was received",
  components: []
})
  .then(console.log)
  .catch(console.error);

formal viper
#

Because a little earlier I tried this method and it's didn't work

deep halo
#

Yes you can. What about it "didn't work"? And please show the part before that line of your code too. The part where you do the actual slicing and defining of components

formal viper
#

My actually code:

let components = interaction.message.components.map(createComponentBuilder)

const index = components[0] - 1

components[0].spliceComponents(index, 1)

await interaction.update({
    components,
    flags: MessageFlags.IsComponentsV2
})```

here is the current error in the console:

4|Signal | [2026-01-02 01:50:28] ERROR: Expected a string primitive
4|Signal | Error: Expected a string primitive
4|Signal | at _StringValidator.handle (/home/bogdan/Signal Bot/node_modules/@sapphire/shapeshift/dist/cjs/index.cjs:2615:70)
4|Signal | at _StringValidator.parse (/home/bogdan/Signal Bot/node_modules/@sapphire/shapeshift/dist/cjs/index.cjs:972:90)
4|Signal | at TextDisplayBuilder.toJSON (/home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2074:33)
4|Signal | at /home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2535:64
4|Signal | at Array.map (<anonymous>)
4|Signal | at SectionBuilder.toJSON (/home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2535:35)
4|Signal | at /home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2237:64
4|Signal | at Array.map (<anonymous>)
4|Signal | at ContainerBuilder.toJSON (/home/bogdan/Signal Bot/node_modules/@discordjs/builders/dist/index.js:2237:35)
4|Signal | at /home/bogdan/Signal Bot/node_modules/discord.js/src/structures/MessagePayload.js:151:46

rancid walrus
#

what's that index for

#

besides producing NaNs

formal viper
rancid walrus
#

but object minus 1 is not going to be even close to that

#

you can't substract a number from a random object and expect that to give you a last component out of the array that random object is in

formal viper
#

oh, k

tepid flame
formal viper
#

I did this because I was told it would work

rancid walrus
#

putting -1 as first argument

rancid walrus
#

not doing it to an object

formal viper
#

uh... and what I'm should to do?

dreamy nest
#

not sure what your current code looks like but as mentioned above, #1456062260748226695 message is correct
that being said, I believe you still need to call <Component>.toJSON() before passing the data to createComponentBuilder
otherwise it results in nested data properties in each component builder
I believe this would be what causes your Expected a string primitive errors

formal viper
#

what is the more correct way to parse data in createComponentBuilder in my case?

const components = interaction.message.components
let component = components[0]
component = component.toJSON()
component = component.createComponentBuilder()

component.spliceComponents(-1, 1)

await interaction.update({
    component
})
dreamy nest
#

ok this code in particular makes me worry you're just guessing and potentially even need to brush up on your js fundamentals

  1. using components.map() was fine, you'd just need to use a quick arrow function instead of passing createComponentBuilder to <Array>.map() directly
  2. the message option is components, so interaction.update({ component }) won't behave the way you want it to
formal viper
formal viper
#

damn

#

it's working

#

Thank you all for your help, especially @dreamy nest