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
Related
I am implementing payment gateway with paystack for the first time and I really don't want to use third party packages for paystack. It is a React Native application. I wanted to implement it using react native webview. It is working so far but I can't seem to get the cancel button to work. This is because the button is not responding when clicked. If the button responded and invoked the paystack onClose URL https://standard.paystack.co/close, I would have simply checked for it and close the webview state.
So, how do I handle this? The button can't be there without doing anything. Can I use javascript and hide it and create my own custom button that actually works on click?: Here is the code I have tried so far:
const { url } = value
if (!url) return;
webView.current.injectJavaScript(handleCancle)
const customUrl = url.split('?');
const getCallBackURL = customUrl[0];
const queryStr = customUrl[1]
if(getCallBackURL == callback_url){
setPaymentState(false);
try {
const res = await axios.get(`${BASE_URL}/payverify/?${queryStr}`);
if(res?.data?.status == 'success'){
const payMentData = res?.data
navigation.navigate('ThankyouPage', {payMentData})
}
} catch (error) {
}
}
The code that tried listening to button click but not working:
const handleCancle = `
var buttons = document.getElementsByTagName('button');
buttons.forEach((button)=>{
if(button.innerHTML.includes('Cancel Payment')){
button.addEventListener("click", function() {
console.log('it has happened')
var resp = {event:'cancelled'};
window.ReactNativeWebView.postMessage(JSON.stringify(resp))
});
}
})
}
`
The webview:
{
isPaymentSuccess && paymentState &&
<WebView
javaScriptEnabled={true}
source={{ uri: paymentData }}
style={{ marginTop: 50 }}
onNavigationStateChange={ handleNav }
cacheEnabled={false}
cacheMode={'LOAD_NO_CACHE'}
ref={webView}
onMessage={(e) => {
console.log('pressed')
console.log(e.nativeEvent?.data)
}}
/>
}
The error so far: No error. No response when the cancel button is clicked!
This is a Puppeteer script running on Apify, designed to enter values into a form and save it. The fields are an input and a textarea, respectively.
The problem is - while the values of both fields are getting successfully updated in the front end (evidenced by taking screenshots), the value of the textarea is not actually saved when the Save <button> is .clicked, even though the input value alone is saved.
Why is this happening, and how do I overcome it?
I have tried several different methods of entering the textarea text:
Unlike the input, I have opted against using .type for the textarea (even though it worked fine for small amounts of text) due to the volume of the text being entered - it was causing timeouts.
I have tried using wait times, artificially changing focus and clicking into the textarea followed by .typeing an arbitrary value. In no circumstance does the textarea value get saved.
I have read on Stackoverflow that textareas should be edited via .innerText rather than .value, but this seems to make no difference in my case.
FYI - the form only becomes visible and active when the user/script clicks an Edit button (before this, the page had showed the form fields as static content). After the single Edit is clicked, two Save buttons appear (.edit-video-info becomes .save-video-info At the top, and then another .save-video-info appears. But a) the script simply uses the first one found and b) the Save operation is otherwise successful, as borne out by the input value getting saved.
import { Actor } from 'apify';
import { PuppeteerCrawler } from 'crawlee'; // "puppeteer" must be included in package.json dependencies
await Actor.init();
console.log('Actor initialised.')
console.log('Welcome. Only run if input was passed...')
const input = await Actor.getInput();
if (input) {
console.log('Input was passed...')
console.log(input);
// Create an instance of the PuppeteerCrawler class - a crawler
// that automatically loads the URLs in headless Chrome / Puppeteer.
const crawler = new PuppeteerCrawler({
// Here you can set options that are passed to the launchPuppeteer() function.
launchContext: {
launchOptions: {
headless: true,
// Other Puppeteer options
defaultViewport: { width: 1800, height: 2100 }
},
},
requestHandlerTimeoutSecs: 180,
// Stop crawling after several pages
maxRequestsPerCrawl: 50,
async requestHandler({ request, page, enqueueLinks }) {
/************************************
* Function: Long-text workaround - used for body
************************************/
// workaround cf. https://github.com/puppeteer/puppeteer/issues/4192#issuecomment-475241477
async function setSelectVal(sel, val) {
page.evaluate((data) => {
return document.querySelector(data.sel).value = data.val
}, { sel, val })
}
console.log(`Processing ${request.url}`);
/************************************
* Authentication
************************************/
let isLoggedIn = false;
// Is site logged-in? true/false
const loggedCheck = async (page) => {
try {
await page.waitForSelector('input#user', { timeout: 10000 });
console.log('Logged-in: true.');
return true;
}
catch(err) {
console.log('Logged-in: false.');
return false;
}
};
isLoggedIn = await loggedCheck(page);
if (!isLoggedIn) {
console.log('Need to do login...');
const SECRET_EMAIL = 'MYEMAILADDRESS'
const SECRET_PASSWORD = 'MYPASSWORD'
await page.waitForSelector('#signinButton')
console.log('Entering email...');
await page.type('input#email', SECRET_EMAIL)
console.log('Entering password...');
await page.type('input#password', SECRET_PASSWORD)
console.log('Clicking #signinButton...');
await page.click('#signinButton')
console.log('Clicked #signinButton.');
isLoggedIn = await loggedCheck(page);
console.log('Login should now be true.');
console.log(isLoggedIn);
}
/************************************
* Kicking off...
************************************/
console.log('Do stuff when #video-details loads...');
await page.waitForSelector('#video-details', { timeout: 30000 })
// Increase browser size
await page.setViewport({
width: 1200,
height: 2400,
deviceScaleFactor: 1,
});
console.log('Existing video title...');
console.log(await page.evaluate(() => document.evaluate('normalize-space(//div[#data-test-name="video-name"]/div[2])', document, null, XPathResult.STRING_TYPE, null).stringValue));
console.log('Echoed.');
/************************************
* Edit video details...
************************************/
console.log('Clicking Edit button...');
await page.click('button[data-test-name=edit-video-info]')
console.log('Clicked Edit button.');
/************************************
* 1. Video title
************************************/
console.log('Wait for input field...');
await page.waitForSelector('label[data-test-name=video-name-input]', { timeout: 30000 })
console.log('OK.');
console.log('Changing video title...')
if (input.title) {
console.log('input.title is available')
const titlebox = await page.$('label[data-test-name=video-name-input] input');
await titlebox.click({ clickCount: 3 })
await titlebox.type(input.title);
console.log('OK')
} else {
console.log('No input.title - will not change.')
}
/************************************
* 2. Body text
************************************/
console.log('Wait for body textarea...');
await page.waitForSelector('label[data-test-name=long-description-textarea] textarea', { timeout: 30000 })
console.log('OK.');
console.log('Changing body text...')
if (input.body) {
console.log('input.body is available')
const bodytext = input.body;
console.log(bodytext);
await setSelectVal('label[data-test-name=long-description-textarea] textarea', bodytext)
console.log('OK')
} else {
console.log('No input.body - will not change.')
}
/* Screenshot */
const screen07typedinput = await page.screenshot();
await Actor.setValue('screen07typedinput.png', screen07typedinput, { contentType: 'image/png' });
/************************************
* Save video details
************************************/
// await page.focus('button[data-test-name=save-video-info]')[1];
await page.waitForTimeout(3000)
console.log('Clicking Save button...');
await page.click('button[data-test-name=save-video-info]')
console.log('Did stuff');
/* Screenshot */
const screen08aftersave = await page.screenshot();
await Actor.setValue('screen08aftersave.png', screen08aftersave, { contentType: 'image/png' });
/************************************
* Logout
************************************/
console.log('Trying logout...')
await page.goto('https://signin.example.com/logout');
console.log('Finished.');
},
// This function is called if the page processing failed more than maxRequestRetries+1 times.
failedRequestHandler({ request }) {
console.log(`Request ${request.url} failed too many times.`);
},
});
// Run the crawler and wait for it to finish.
// await crawler.run(['https://news.ycombinator.com/']);
await crawler.run(['https://site.example.com/products/videocloud/media/videos/'+input.assetid]);
console.log('Crawler finished.');
} else {
console.log('No input. Abandon.')
}
await Actor.exit();
The button markup is...
<button class="Button-blueSteel-4_1_4-3Skod Button-btn-4_1_4-QuPwe Button-primary-4_1_4-2YCmt Button-small-4_1_4-1Wurh" data-test-name="save-video-info" role="button" tabindex="0" type="button" aria-pressed="true">
<span class>Save</span>
</button>
An id attribute is absent, so I can't use getElementByID.
This works...
I had not .clicked inside the <textarea>.
Whilst I had .clicked the <input> field prior to .typeing into it, I had not done this with the <textarea> - because I wasn't using .type there; I was having to set the `.values.
In addition to that, for good measure, I .click Back in to the <input> field.
Also, I `.types an arbitrary value.
I think it was the clicks. Without having clicked the <textarea>, only the apparent .value was getting set.
await page.click('label[data-test-name=long-description-textarea] textarea')
await setSelectVal('label[data-test-name=long-description-textarea] textarea', bodytext)
await page.click('label[data-test-name=long-description-textarea] textarea')
await page.type('label[data-test-name=long-description-textarea] textarea',' ')
await page.click('label[data-test-name=video-name-input] input')
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:[]});
}
})
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') {
// ...
I'm not able to display the picture of a logged user with email/password inside an <img> tag. I could display correctly the email,uid and all the details but the picture. This is the code:
HTML:
<img id="user-image">
Js:
firebase.auth().onAuthStateChanged(function(user) {
var userId = firebase.auth().currentUser;
var picture;
if (userId) {
picture = userId.photoURL;
document.getElementById("user-image").src = picture;
} else {
//Nothing;
}
});
When I go to the console I get error 404/null. Yes, the user Do have a picture ,I tried already with the exact path of the image file and it works.
Thanks.
Why do you call firebase.auth().currentUser; when you already have the user as a parameter of the function that is triggered on change?
What do you get if you do as follows:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
var picture = user.photoURL;
console.log(picture). // <- check in you console that you get the correct url
document.getElementById("user-image").src = picture;
} else {
//Nothing;
}
});