How can I fix this error "Cannot set properties of undefined" - discord.js

const { Client, Intents, MessageEmbed } = require('discord.js');
let client = new Client({ intents: [Intents.FLAGS.GUILDS,Intents.FLAGS.GUILD_MESSAGES] });
const dotenv = require('dotenv');
const Keyv = require('keyv');
const keyv = new Keyv();
dotenv.config();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async (msg) => {
let number = msg.content.split(' ')[1];
if (msg.content === '!ping') {
msg.channel.send('ping!')
}
`
const getGuildPrefix = async () => {
const prefixMap = await keyv.get('prefix');
return prefixMap ?. [msg.guild.id] || "!"
}
// Sets the prefix to the current guild.
const setGuildPrefix = async (prefix) => {
const prefixMap = await keyv.get('prefix');
prefixMap[msg.guild.id] = prefix;
await keyv.set('prefix', `${prefixMap}`);
}
let prefix = await getGuildPrefix();
// Get prefix command.
if ((msg.content === `${process.env.prefix}prefix`) || (msg.content === `${prefix}prefix`)) {
msg.channel.send(`Your server prefix is ${prefix}`)
}
})
client.login(process.env.token);
So what this code does is retreive prefix for a particular server in which different server have different prefix, so I used keyv package for storing the prefix, but I am getting an error and this is the error message
prefixMap[msg.guild.id] = prefix;
^
TypeError: Cannot set properties of undefined (setting '857122654976606239')
at setGuildPrefix
Here if the value in the key is empty, then it is supposed to return the value "!" by default. So this is almost the same code I did yesterday, but I edited the code a little bit to fix the error in getGuildPrefix, and now I am getting this error. Both the errors are caused because of undefined but I used optional chaining to fix the first one, and the getGuildPrefix is working fine, but there is now an error in the setGuildPrefix part. The thing is even if PrefixMap is undefined, the value is supposed to be "!", the code is in that way (I assume, but not very sure though). How can I fix this error?

I think your logic syntax might be wrong here, try
const getGuildPrefix = async () => {
const prefixMap = await keyv.get('prefix');
if(!prefixMap[msg.guild.id]) {
return prefixMap[msg.guild.id];
}
else {
return '!';
}
};

the value which is supposed to return is !, but we gave it only in the getGuildPrefix, but we cant do optional chaining in the setGuildPrefix because it gives an error like left hand, so if keyql doesn't return a value from db again, then we can iniatite it again within the if statement again but using another if statement. we cant use this technique in the getGuildPrefix idk why, but we can use this in setGuildPrefix and we can use optional chaining in getGuildPrefix and now the error is fixed, and the code is working functionally
client.on('messageCreate', async (msg) => {
let number = msg.content.split(' ')[1];
if (msg.content === '!ping') {
msg.channel.send('ping!')
}
// Use this function to get the prefix in other files.
// Use like `const prefix = await getGuildPrefix();`
const getGuildPrefix = async () => {
const prefixMap = await keyv.get('prefix');
return prefixMap ?. [msg.guild.id] || "!"
}
// Sets the prefix to the current guild.
const setGuildPrefix = async (prefix) => {
let prefixMap = await keyv.get('prefix');
if (!prefixMap)
{
prefixMap = "!";
}
prefixMap[msg.guild.id] = prefix;
await keyv.set('prefix', `${prefixMap}`);
}
let prefix = await getGuildPrefix();
// Get prefix command.
if ((msg.content === `${process.env.prefix}prefix`) || (msg.content === `${prefix}prefix`)) {
msg.channel.send(`Your server prefix is ${prefix}`)
}
})
client.login(token)

Related

React Native Route.params Set/ Get Asyncstorage

const { MoodNameResult } = this.props.route.params == undefined ? this.props.route.params = "asd" : this.props.route.params;
const asd = [] + MoodNameResult;
const storeData = async (value) => {
try {
const jsonValue = JSON.stringify(value)
await AsyncStorage.setItem('#MoodNameResult', jsonValue)
} catch (e) {
// saving error
}
}
const getData = async () => {
try {
const jsonValue = await AsyncStorage.getItem('#MoodNameResult')
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch (e) {
// error reading value
}
}
console.log(getData());
On the last page "Would you like to score again?" I ask the question and if "yes" is said, I am directed to the score page with the data in the MoodNameResult. When I checked, the data in the MoodNameResult I received using Route.params is correct, but I cannot save the data from Route.params to Asyncstorage. I'm new, I always get an error when I research and apply a few resources.

How to check if a certain key name exist in json object in React app

I create this custom hook in my React app. It should return a boolean.
const useFetchResponse = (url: string) => {
const [isValid, setIsValid] = useState<boolean>(false);
useEffect(() => {
const fetchResponse = async () => {
const response = await fetch(url);
console.log(response);
const obj = await response.json();
if (response.ok) {
console.log(await response.json());
setIsValid(true);
}
return response;
};
fetchResponse().then((res) => res);
}, []);
return isValid;
};
export default useFetchResponse;
When I log const obj = await response.json(); it returns: {"keyName":"some=key"}.
How do I create a condition to check if response.json() has a key named keyName?
Is that for example console.log('keyName' in obj) // true?
Do you see more things which I can improve and refactor?
Let assume you get response as follow
let response = {
a:'data1',
b:'data2',
c:'data3'
};
Then you can extract keys from object as below:
let keyOnly = Object.keys(response)); // output will be ["a","b","c"]
then you can check if your require value includes on above array or not as below: Assuming if you want to check if "b" is included or not
let checkKey = keyOnly.includes(b)
if you want to check whether an object has a certain property or not, the in operator is fine.
const obj = { a: 1 };
'a' in obj // return true
'b' in obj // return false
About improvements
it's better to save all fetch states, not only valid or not. And you should wrap request with try/catch block. For example:
const [fetchState, setFetchState] = useState('pending');
useEffect(() => {
const fetchResponse = async () => {
try {
setFetchState('loading');
const response = await fetch(url);
console.log(response);
const obj = await response.json();
if (response.ok) {
console.log(await response.json());
setFetchState('success');
}
return response;
} catch (error) {
setFetchState('failed')
}
};
fetchResponse().then((res) => res);
}, []);
return fetchState;
};
fetchResponse(); would be enough. fetchResponse().then((res) => res); is unnecessary.
[optional] You could use libraries to making requests, like an axios. That would be more convenient.
in is slower than below way.
const isValid = obj[`keyname`] !== undefined
Check more detail in here

MessageEmbed is not a constructor

I'm getting an error "MessageEmbed is not a constructor" it works with only sending a message, but not with an embed. What could be this issue?
const MessageEmbed = require('discord.js');
const { Manager } = require('erela.js');
const nodes = require('./Nodes');
module.exports = (client) => {
client.manager = new Manager({
nodes,
send(id, payload) {
const guild = client.guilds.cache.get(id);
if (guild) guild.shard.send(payload);
}
})
.on('nodeConnect', node => console.log(`Node ${node.options.identifier} connected.`))
.on('nodeError', (node, error) => console.log(`Node ${node.options.identifier} had an error: ${error.message}.`))
.on('trackStart', (player, track) => {
client.channels.cache
.get(player.textChannel)
.send(new MessageEmbed().setDescription(`Now playing: \`${track.title}\``).setColor('ORANGE'));
})
.on('queueEnd', (player) => {
client.channels.cache
.get(player.textChannel)
.send(new MessageEmbed().setDescription('The queue has ended. Leaving the channel.').setColor('ORANGE'));
player.destroy();
});
};
const MessageEmbed = require("discord.js")
is incorrect. The correct way is:
const { MessageEmbed } = require("discord.js")
Note the {}. The curly braces are a destructuring assignment. When you import or require discord.js, it is importing an object with everything in discordjs. By using destructuring assignment, you are only picking out the parts you require.

Why is data not being saved in the array? | discord.js v13

Whenever I'm attempting to push data into an array, then log it after the for loop it just prints an empty array. Why is that?
const discord = require('discord.js');
const db = require('quick.db');
const fs = require('fs');
module.exports = {
name: 'XYZ',
run: async (client, message) => {
var array_V = ['ID1', 'ID2'];
var snowflakes = [];
var i = 0;
message.guild.channels.cache.forEach(channel => {
if (!channel.isText()) return;
for (const channel of message.guild.channels.cache.values()) {
let messages = await channel.messages.fetch()
messages.each((msg) => {
if (msg.author.id === array_V[i]) {
snowflakes.push(msg.createdTimestamp)
}
})
}
});
}
}
Now outputs SyntaxError: await is only valid in async functions and the top level bodies of modules although it is already declared as an async function in the header.
You are pushing it in a .then. Use await and for loops to have it update and then run the next code
for (const channel of message.guild.channels.cache.filter(c => c.type === "GUILD_TEXT").values()) {
let messages = await channel.messages.fetch()
messages.each((msg) => {
if (msg.author.id === array_V[i]) {
snowflakes.push(msg.createdTimestamp)
}
})
}
This should work since everything asynchronous is being awaited in the for loop

How to transfer reaction to original message, discord.js

I am trying to make a suggestion feature for one of my bots. I have searched online but nothing really helps with it. The suggestion part is working but I want to add a feature where if i react to the message in the log channel it sends the reaction to the original message. Here is my code:
bot.on('message', message => {
if (message.content.startsWith("/suggest")){
message.reply(`Your response has been recorded.`)
var yes = message.content
const channel1 = bot.channels.cache.get('722590953017442335');
channel1.send(`${message.author} suggests: ${yes.slice(9)}`)
if (chanell1.reaction.emoji.name === '✅'){
const channel2 = bot.channels.cache.get('722595812462297139');
channell2.react.author.message('✅')
}
}
})
I am using v12 of node.
You can use the awaitReactions() function:
bot.on("message", (message) => {
if (message.content.startsWith("/suggest")) {
message.reply(`Your response has been recorded.`);
var yes = message.content;
bot.channels.cache
.get("722590953017442335")
.send(`${message.author} suggests: ${yes.slice(9)}`)
.then(async (msg) => {
msg
.awaitReactions((reaction) => reaction.emoji.name === "✅", {
time: 15000,
})
.then((collected) => message.react("✅"))
.catch(console.error);
});
}
});
Please read the official documentation at https://discord.js.org/#/docs/main/v12/general/welcome for v12 help. You ought to use the Client#messageReactionAdd event to track reactions - your code isn't too far off, however it is missing that key event. Please note that to track reactions you'll need persistent storage if you want the reactions to work after restart. Alternatively, you could try awaiting the reactions or using a reaction collector if only short term.
Try this instead:
const { Client } = require('discord.js');
const bot = new Client({ partials: ['REACTION', 'USER'] });
const prefix = '/';
const suggestionsCache = {};
bot.on('message', async message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.split(' '),
command = args.shift().slice(prefix.length);
if (command == 'suggest') {
const suggestion = args.join(' '),
suggestionMessage = `${message.author} suggests: ${suggestion}`,
suggestionChannel = bot.channels.cache.get('722590953017442335'),
logChannel = bot.channels.cache.get('722595812462297139');
if (!suggestionChannel || !logChannel) return message.reply('Oops! Something went wrong.');
try {
const suggestionMessage = await suggestionChannel.send(suggestionMessage);
const logMessage = await logChannel.send(suggestionMessage);
suggestionsCache[logMessage.id] = suggestionMessage.id; // Save the ID for later.
message.reply('Your response has been recorded.');
} catch {
message.reply('Oops! Something went wrong.');
};
};
});
bot.on('messageReactionAdd', async (reaction, user) => {
if (reaction.partial) {
try {
await reaction.fetch();
} catch {}
}
const messageID = suggestionsCache[reaction.message.id];
if (!messageID || reaction.emoji.name !== '✅') return; // If not found in cache, ignore and if the emoji isn't the check, ignore it.
try {
const channel = await client.channels.fetch('722590953017442335');
if (!channel) return;
const message = channel.messages.fetch(messageID);
if (!message) return; // Message deleted.
message.react('✅');
} catch {
return;
};
});
Please note that I am new to v12 and normally use v11! The code above is not tested and may contain bugs as a result. Please feel free to edit/update the code.

Resources