#Cutting buttons out of the container
74 messages · Page 1 of 1 (latest)
Edit the message with the components without the ActionRow containing those buttons.
Not sure what you mean
If anything, I'm mean a container like on this screen
I need to either turn them off or completely refresh the message and cut them out
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
K, I'll try it
Do I need to specify components instead of ellipsis?
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
})
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.
So, as I understand it, there are no other options without duplicating the code? Note that my code is structured so that initially this container is formed in one file and sent there. But the reaction to the buttons below is in another file.
And could I see an option to remove the buttons? For the future
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)
ContainerBuilder#spliceComponents() [email protected]
Removes, replaces, or inserts components for this container.
Am I the only one seeing that channel mention as #unknown? ;-;
It's a forum post. It's not cached in your client. Just click it
Could u give more details on how to use ContainerBuilder#spliceComponents?
The docs for it are right here
You set the index of the array to start manipulating, how many components to delete, and any components you might want to add
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.
It behaves just like that ^
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
components there is an Array, spliceComponents doesn't exist on the array but ContainerBuilder
So what is my course of action?
Do you know how to work with arrays?
50-50, depends on the specific tasks
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
I was trying to figure out how to remove specifically the last component of my container (buttons)
Then instead of starting at index 0 in the splice, start at the last index entry (components[0].length - 1 iirc)
oh, like this, ofc?
let components = interaction.message.components.map(createComponentBuilder)
const index = components[0] - 1
components.spliceComponents(index, 1)```
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)```
components[0].spliceComponents(index, 1)
As i said it behaves like Array.splice, so (-1, 1) will work
(I wasn't sure if that works...thanks NyR)
uhm, yes?
let components = interaction.message.components.map(createComponentBuilder)
components[0].spliceComponents(-1, 1)```
Did you try it and see if it worked?
I did it rn
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'```
What's your current code? Can you show?
all file or a specific segment?
The part the error comes from and you just changed according to this posts topic
I think it's:
await interaction.message.edit({
components,
flags: MessageFlags.IsComponentsV2
})
I think that's the most difficult thing I do
@fierce moth What do u think 'bout this?
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
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);
@tepid flame Can I use that without content?
Because a little earlier I tried this method and it's didn't work
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
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
to get the last component with buttons and remove it
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
oh, k
And it is irrelevant anyways as stated here: #1456062260748226695 message
I did this because I was told it would work
putting -1 as first argument
It's returns same error
not doing it to an object
uh... and what I'm should to do?
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
my current code:
let components = interaction.message.components.map(createComponentBuilder())
components[0].spliceComponents(-1, 1)
await interaction.update({
components
})
I'll be editing code now
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
})
ok this code in particular makes me worry you're just guessing and potentially even need to brush up on your js fundamentals
- using
components.map()was fine, you'd just need to use a quick arrow function instead of passingcreateComponentBuilderto<Array>.map()directly - the message option is
components, sointeraction.update({ component })won't behave the way you want it to
I could write hundreds of excuses, like this is a new feature and I haven't worked with it for a long time, but I won't
I'm just sorry that I made you go through so much trouble with me. I'll try to improve my skills
I'll come back with an answer after modifying the code and testing it