Edit components within a container (CV2)

Hi there. Was just wondering if I could get guidance to how I would edit a specific button accessory on a container when calling something like interaction.update. Previous you would just modify the component, but now the entire container in itself is a component, and was hoping I wouldn't have to rebuild the container and pass in the change i made. (Also, perhaps adding a tag for components v2 is a good idea now that it's a fresh feature and people may want to target issues specifically for that?)
5 Replies
d.js toolkit
d.js toolkit3d ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button! - Marked as resolved by OP
d.js docs
d.js docs3d ago
:method: ContainerComponent#toJSON() [email protected] Returns the API-compatible JSON for this component
Ryan
RyanOP3d ago
i know spoon feeding is discouraged and i do not want you to, but could you perhaps send a small snippet of what you mean? i did that initially but typescript complains:
Argument of type 'TopLevelComponent' is not assignable to parameter of type 'Partial<APIContainerComponent> | undefined'.
Type 'ActionRow<MessageActionRowComponent>' is not assignable to type 'Partial<APIContainerComponent>'.
Types of property 'components' are incompatible.
Type 'MessageActionRowComponent[]' is not assignable to type 'APIComponentInContainer[]'.
Type 'MessageActionRowComponent' is not assignable to type 'APIComponentInContainer'.
Type 'ButtonComponent' is not assignable to type 'APIComponentInContainer'.
Property 'components' is missing in type 'ButtonComponent' but required in type 'APIActionRowComponent<APIComponentInMessageActionRow>'
Argument of type 'TopLevelComponent' is not assignable to parameter of type 'Partial<APIContainerComponent> | undefined'.
Type 'ActionRow<MessageActionRowComponent>' is not assignable to type 'Partial<APIContainerComponent>'.
Types of property 'components' are incompatible.
Type 'MessageActionRowComponent[]' is not assignable to type 'APIComponentInContainer[]'.
Type 'MessageActionRowComponent' is not assignable to type 'APIComponentInContainer'.
Type 'ButtonComponent' is not assignable to type 'APIComponentInContainer'.
Property 'components' is missing in type 'ButtonComponent' but required in type 'APIActionRowComponent<APIComponentInMessageActionRow>'
caused by:
const container = new ContainerBuilder(message.components[0]);
const container = new ContainerBuilder(message.components[0]);
Alr fine with that.
Mafia
Mafia3d ago
components have a optional id property that you can use to identify
Ryan
RyanOP2d ago
yep thanks, Qjuh did mention. Thanks again also i'm not sure if this is correct, but when logging the container i noticed incremental ID's. Would I need to setId to something like 50 to avoid issues or does it not matter alr thanks. So even if the component is not necessarily the 1st component, giving it an id of 1 is ok Only got to trying this out today, and what i've done so far:
const initialContainer = message.components[0] as APIContainerComponent;

const container = new ContainerBuilder(initialContainer);

container.components.map((component) => console.log(component));
const initialContainer = message.components[0] as APIContainerComponent;

const container = new ContainerBuilder(initialContainer);

container.components.map((component) => console.log(component));
I notice that it logs this:
SectionBuilder {
data: {
type: 9,
data: {
type: 9,
id: 1,
},
},
components: [...]
SectionBuilder {
data: {
type: 9,
data: {
type: 9,
id: 1,
},
},
components: [...]
-# can share the full log if needed I've explicitly used setId(1) on the initial builder itself like so:
container
.addSectionComponents(
new SectionBuilder()
.addTextDisplayComponents(new TextDisplayBuilder().setContent(...))
.setButtonAccessory(
new ButtonBuilder()
.setLabel(...)
.setCustomId(...)
.setStyle(ButtonStyle.Primary)
)
)
.setId(1); // <= as I want to essentially replace with a new SectionBuilder on button click
container
.addSectionComponents(
new SectionBuilder()
.addTextDisplayComponents(new TextDisplayBuilder().setContent(...))
.setButtonAccessory(
new ButtonBuilder()
.setLabel(...)
.setCustomId(...)
.setStyle(ButtonStyle.Primary)
)
)
.setId(1); // <= as I want to essentially replace with a new SectionBuilder on button click
And noticed that when I do:
container.components.find((component) => component.data.id === 1);
container.components.find((component) => component.data.id === 1);
It will always be undefined since as per the logs, i need to do component.data.data.id but the 2nd .data is not recognized by TS. Did i miss a step/perhaps didn't do the correct typing somewhere? Am i maybe just doing it wrong again lol? Thanks! Even if i want to replace both the TextDisplay and the Accessory? I initially wanted to just do the accessory, but now want to change the entire section itself Yea i understand that, but, I would need to do component.data.data.id for it to find something, since component.data.id always returns undefined - and the 2nd .data is not recognized by ts - i guess my question has shifted a bit now. Does that make sense?
const sectionComponent = container.components.find((component) => component.data.id === 1);

console.log(sectionComponent); // < undefined
const sectionComponent = container.components.find((component) => component.data.id === 1);

console.log(sectionComponent); // < undefined
const sectionComponent = container.components.find((component) => component.data.data.id === 1);

console.log(sectionComponent); // correctly logs the component
const sectionComponent = container.components.find((component) => component.data.data.id === 1);

console.log(sectionComponent); // correctly logs the component
But 2nd approach has a ts error:
Property 'data' does not exist on type 'Partial<APIActionRowComponent<APIComponentInMessageActionRow | APITextInputComponent>> | ... 4 more ... | Partial<...>'.
Property 'data' does not exist on type 'Partial<APIActionRowComponent<APIComponentInMessageActionRow | APITextInputComponent>>'
Property 'data' does not exist on type 'Partial<APIActionRowComponent<APIComponentInMessageActionRow | APITextInputComponent>> | ... 4 more ... | Partial<...>'.
Property 'data' does not exist on type 'Partial<APIActionRowComponent<APIComponentInMessageActionRow | APITextInputComponent>>'
@Qjuh Just wanted to apologize. I completely forgot the initial thing you mentioned - toJSON Adding that fixed everything. That's completely my bad. For anyone else just joining in:
const initialContainer = message.components[0].toJSON() as APIContainerComponent;
const initialContainer = message.components[0].toJSON() as APIContainerComponent;
was the fix

Did you find this page helpful?