why this modal didnt show up? - javascript

I have this modal command, I want to make a modal shown to the user when they use the command modal. Is there anything wrong with the following code?
const { MessageActionRow, Modal, TextInputComponent } = require('discord.js');
client.on('interactionCreate', async (msg) => {
if(msg.content === 'modal') {
// Create the modal
const modal = new Modal()
.setCustomId('myModal')
.setTitle('My Modal');
// Add components to modal
// Create the text input components
const favoriteColorInput = new TextInputComponent()
.setCustomId('favoriteColorInput')
// The label is the prompt the user sees for this input
.setLabel("What's your favorite color?")
// Short means only a single line of text
.setStyle('SHORT');
const hobbiesInput = new TextInputComponent()
.setCustomId('hobbiesInput')
.setLabel("What's some of your favorite hobbies?")
// Paragraph means multiple lines of text.
.setStyle('PARAGRAPH');
// An action row only holds one text input,
// so you need one action row per text input.
const firstActionRow = new MessageActionRow().addComponents(favoriteColorInput);
const secondActionRow = new MessageActionRow().addComponents(hobbiesInput);
// Add inputs to the modal
modal.addComponents(firstActionRow, secondActionRow);
// Show the modal to the user
await msg.showModal(modal);
}
});

The interactionCreate event is emitted when an interaction is created and takes a single parameter, an Interaction that was created. It's not a message and has no content property. As msg.content is undefined, it will never match the string "modal" so everything inside that if statement is ignored.
If you want to check if someone sent a message with the word modal as its content, you can use the messageCreate event:
client.on('messageCreate', async (msg) => {
if (msg.content === 'modal') {
// ...
The problem is, that message doesn't have a showModal() method, only CommandInteraction, ButtonInteraction, SelectMenuInteraction, etc do.
If you use the interactionCreate event, you'll need to check the command name, button ID, etc instead:
client.on('interactionCreate', async (interaction) => {
if (interaction.isCommand() && interaction.commandName === 'modal') {
// ...
// OR
if (interaction.isButton() && interaction.customId === 'modal') {
// ...

Related

Interaction has already been acknowledged when responding to the second embed after the first embed, button discord.js

There's a ton of threads there already I know but I still can't get it to work. I'm building an embed with a button. The embed appears using command $test. The error happens when I trigger the embed for the second time (2nd $test) and click the button after clicking the button on the first trigger.
This flow should work but the error "Interaction has already been acknowledged" triggers.
Steps:
Type $test to show the embed.
User clicks "Click me." button on the embed.
The embed updates to embed2 confirming the click on the button.
Type $test again to show the embed.
User clicks "Click me." button on the embed.
Result: Interaction has already been acknowledged.
Expected Result: The 2nd embed should be totally new. It should not remember my first interaction on the 1st embed.
Should I use .reply() instead of .update()? Does that matter?
I read a post saying this:
Interaction has already been acknowledged happens when you try to
reply to the interaction that you already replied, and you can fix it
by using .editReply() after you .reply() the interaction.
Here's the code:
client.on("messageCreate", (message) => {
if (command === "test") {
const button = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId("button1")
.setLabel("Click me.")
.setStyle(ButtonStyle.Secondary)
);
const embed = new EmbedBuilder()
.setColor("#5A5A5A")
.setTitle("Embed")
.setDescription("Did you receive this message? Click button if you did.")
const embed2 = new EmbedBuilder()
.setColor("#5A5A5A")
.setTitle("Confirmation Embed")
.setDescription("Thanks for confirming!")
message.channel.send({embeds:[embed], components:[button]});
const collector = message.channel.createMessageComponentCollector();
collector.on("collect", (i) => {
if(i.customId === "button1") {
i.update({embeds: [embed2], components:[]});
}
})
});
the collector is in the channel you should tie it to the message
client.on("messageCreate", async (message) => {
if (command === "test") {
const button = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId("button1")
.setLabel("Click me.")
.setStyle(ButtonStyle.Secondary)
);
const embed = new EmbedBuilder()
.setColor("#5A5A5A")
.setTitle("Embed")
.setDescription("Did you receive this message? Click button if you did.")
const embed2 = new EmbedBuilder()
.setColor("#5A5A5A")
.setTitle("Confirmation Embed")
.setDescription("Thanks for confirming!")
const msg = await message.channel.send({embeds:[embed], components:[button]});
const collector = msg.createMessageComponentCollector();
collector.on("collect", (i) => {
if(i.customId === "button1") {
i.update({embeds: [embed2], components:[]});
}
})
});
You need to defer the update.
This can either be done directly by replying to an interaction using i.reply() or by using await i.deferUpdate(); after the button is pressed.
Since you need to edit an already existing interaction, you need to use the second option.
Example:
collector.on("collect", (i) => {
if(i.customId === "button1") {
await i.deferUpdate();
i.update({embeds: [embed2], components:[]});
}
})

Axois error on doing work with the dbd and nodejs

I am making a chat application that is setting an avatar image and when i set a avatar image then in the user that is already register and persent in my db i.e. mongo
And am setting the image and here is the code of my function that will set the avatar image in my db
`
const setProfilePicture = async () =>{
if(selectedAvatar === undefined){
toast.error("Please select an Avatar", toastOptions)
}else{
const user = await JSON.parse(localStorage.getItem("chat-app-user"));
const {data} = await axios.post(`${setAvatarRoute}/${user._id}`,{
image:avatars[selectedAvatar],
});
if(data.isSet){
user.isAvatarImageSet = true;
user.avatarImage = data.image;
localStorage.setItem("chat-app-user", JSON.stringify(user));
navigate("/")
}else{
toast.error("Error setting avatar. Please try again", toastOptions)
}
}
}
`and here my console that raising the error on clicking the button
Button that has onClick event enter image description here

Does anyone know why this code is not working the way I want it to?

I am creating a web app with node.js, express and pug templates and here I am trying to simulate a warning when the user tries to remove a review he has posted.
so, in the front end I have a button that the user clicks to remove his review
when the user clicks that button I run
index.js
import { showWarning } from './warning';
const removerStoreReviewBtn = document.querySelector('.side-nav__removeStoreReviewbtn');
if (removerStoreReviewBtn)
removerStoreReviewBtn.addEventListener('click', e => {
e.preventDefault();
showWarning('Would you like to remove this review ?');
});
warning.js
export const hideWarning = () => {
const el = document.querySelector('.warning');
const warningText = document.querySelector('.warning__text');
if (el) el.parentElement.removeChild(el);
if (warningText) warningText.parentElement.removeChild(warningText);
};
export const showWarning = (msg, time = 30) => {
hideWarning();
console.log(msg);
const markUp = `
<div class="warning">
<div class="warning__text">${msg}</div>
<button class="warning--no">
<span>Cancelar</span>
</button>
<button class="warning--yes">
<span>Apagar</span>
</button>
</div>`;
document.querySelector('.header').insertAdjacentHTML('afterend', markUp);
window.setTimeout(hideWarning, time * 1000);
};
The showWarning function display everything the way I want in the front end
then back at the index.js file I have the following code
index.js
const warningBtnYes = document.querySelector('.warning--yes');
const warningBtnNo = document.querySelector('.warning--no');
if (warningBtnYes)
warningBtnYes.addEventListener('click', e => {
e.preventDefault();
console.log('remove');
//removerStoreReview(reviewId);
});
if (warningBtnNo)
warningBtnNo.addEventListener('click', e => {
e.preventDefault();
console.log('Do not remove');
});
when I click any of these buttons nothing happens (I am expecting the console.logs) and I can't figure out why nothing happens, hopefully anyone can help me.
Thanks
Mateus
When you use .parentElement.removeChild() you have turned off all event listeners for those button.
You have two options. You can preserve the event listeners by storing the return value from the .removeChild() call. In order to restore the event listeners you will need to reuse the stored (previously removed) node.
Alternatively, you'll need to re-add your event listeners after inserting the new HTML.
Helpful docs

JavaScript single page application, how to display correct HTML after form submission?

I am writing an email client as a single page application using AJAX. I have a button that brings you to a form where a user can enter the required details to send an email which you can submit using a button. What I want to have happen is upon submitting an email, be brought to the user's sent mailbox, but currently it always routes to the default inbox view. I believe this is because of the way I have a DOMContentLoaded event listener set up:
document.addEventListener('DOMContentLoaded', function() {
// Use buttons to toggle between views
document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
document.querySelector('#compose').addEventListener('click', compose_email);
// By default, load the inbox view
load_mailbox("inbox");
});
This listener simply sets up the navigation buttons and sets the default mailbox. The load_mailbox function is a simple function that takes in a string of the desire mailbox to see and manipulates the DOM accordingly. Here is my compose_email() function that is intended to handle showing the sending an email form and handling submission.
function compose_email() {
// Show compose view and hide other views
document.querySelector('#emails-view').style.display = 'none';
document.querySelector('#open-mail-view').style.display= 'none';
document.querySelector('#compose-view').style.display = 'block';
// Clear out composition fields
document.querySelector('#compose-recipients').value = '';
document.querySelector('#compose-subject').value = '';
document.querySelector('#compose-body').value = '';
// Handle sending an email, return to sent inbox after TODO: Not returning to sent inbox
let form = document.querySelector('#compose-form');
form.addEventListener('submit', function() {
const recipients = document.querySelector('#compose-recipients').value;
const subject = document.querySelector('#compose-subject').value;
const body = document.querySelector('#compose-body').value;
fetch('/emails', {
method: 'POST',
body: JSON.stringify({
recipients: recipients,
subject: subject,
body: body
})
})
.then(response => response.json())
.then(result => {
console.log(result);
})
load_mailbox('sent'); //This is not working!!! What to do?
});
}
After submission, I want the user to be shown their sent mailbox, which is currently not happening. This is presumably because the DOMContentLoaded listener immediately gets triggered and brought to the "inbox" mailbox.
How can I go about having the user see the sent mailbox DOM content while still maintaing the inbox mailbox as a default (upon refresh, initially opening the site, etc..)?
The form submission is causing a page reload because the default action isn't prevented.
Firstly, start capturing the event object:
form.addEventListener('submit', function(ev) { ...
then
ev.preventDefault();
(...and to be extra-sure)
//...
load_mailbox('sent');
return false;
at the end of the handler (not in the promise callbacks)

How to get the buttons in a 'dialog.showMessageBoxSync' to work in Electron.js

In my electron application, I have a .showMessageBoxSync message box with two buttons that displays if the user doesn't have a internet connection or not. The message box itself works, but the buttons on the box won't fire the functions like it is supposed to. When I click "Try again please" button, the box just closes. It does the same with the other button. I'd like to test the internet connection again if the user would like to, so I tried to call the 'execute()' method again, but to no avail.
Here is my code -
function secondOnline(user_callback){
const message = () => {
return dialog.showMessageBoxSync(null, {
title:"Connection Status",
message:"No internet available, do you want to try again?",
type:'warning',
buttons:["Try again please","No, thanks"]
}, (result) => {
if(result === 0){
execute();
}
})
};
const secondMessage = () => {
return dialog.showMessageBoxSync({
title:"Connection Status",
message:"Internet connected.",
type:'info'})
};
const execute = () => {
if(navigator.onLine){
secondMessage()
}else{
message();
}
};
execute();
}
Any ideas?
Thanks.

Categories

Resources