.find() with Discord Bots - javascript

Let's say i have this:
let res = body.classes.find(c => c.name.toLowerCase() === args[0].toLowerCase()) || body.typedefs.find(t => t.name.toLowerCase() === args[0].toLowerCase())
How would I check if the output of res is from body.classes or body.typedefs?

The output will be from body.classes if body.classes.find instruction returns something. Else, it will be the result from body.typedefs.find.
const body = {
classes: [
{ name: 'name1' },
{ name: 'name2' },
{ name: 'name3' },
],
typedefs: [
{ name: 'name1' },
{ name: 'name2' },
{ name: 'name3' },
{ name: 'name4' }
]
};
const arg1 = 'NAME1';
const res1 = body.classes.find(c => c.name.toLowerCase() === arg1.toLowerCase()) || body.typedefs.find(t => t.name.toLowerCase() === arg1.toLowerCase());
console.log(res1);
const arg2 = 'NAME4';
const res2 = body.classes.find(c => c.name.toLowerCase() === arg2.toLowerCase()) || body.typedefs.find(t => t.name.toLowerCase() === arg2.toLowerCase());
console.log(res2);
So if you want to check if the output is from body.classes or from body.typedefs, you just have to store the output of each find function in different variables and then check them. Something like
const findClasses = body.classes.find(c => c.name.toLowerCase() === args[0].toLowerCase());
const findTypedefs = body.typedefs.find(c => c.name.toLowerCase() === args[0].toLowerCase());
let res = findClasses || findTypedefs;
if (findClasses) {
console.log('Ouput from body.classes.find:', findClasses);
}
if (findTypedefs) {
console.log('Ouput from body.typedefs.find:', findTypedefs);
}

Related

How to remove mutation on this code Javascript?

I managed to write code which does what I need, but I want to make it clean and remove mutation of realtiveGroups.push() but don't know how to achieve it.
How to remove mutation from this code?
export interface OfferCategory {
id: string;
name: string;
}
export interface OfferGroup {
groupId: string;
dependsOn: OfferCategory;
name: string;
rule: Rule;
products: PosProducts[];
}
function relativesFromSubscription(groups: OfferGroup[], dependingGroups: OfferGroup[]): OfferGroup[] {
const relativeGroups: OfferGroup[] = [];
groups.forEach(group => {
if (dependingGroups.some(dependingGroup => group?.dependsOn?.id === dependingGroup.groupId)) {
relativeGroups.push(group);
}
if (relativeGroups.some(relativeGroup => group?.dependsOn?.id === relativeGroup.groupId)) {
relativeGroups.push(group);
}
});
return relativeGroups;
}
Instead of doing everything in one cycle try dividing it into a few:
function relativesFromSubscription(groups: OfferGroup[], dependingGroups: OfferGroup[]): OfferGroup[] {
const groups1 = groups.filter(group => dependingGroups.some(dependingGroup => group?.dependsOn?.id === dependingGroup.groupId));
const groups2 = groups.filter(group => groups1.some(relGroup=> group?.dependsOn?.id === relGroup.groupId));
return [...groups1, ...groups2];
}
Using your code and Array.filter
const relativeGroups: OfferGroup[] = groups.filter(group => {
return dependingGroups.some(dependingGroup => group?.dependsOn?.id === dependingGroup.groupId) || relativeGroups.some(relativeGroup => group?.dependsOn?.id === relativeGroup.groupId)
});
Or if you want the code to be more readable you can add descriptive variables:
const relativeGroups: OfferGroup[] = groups.filter(group => {
const hasDependingGroups = dependingGroups.some(dependingGroup => group?.dependsOn?.id === dependingGroup.groupId);
const hasRelativeGroups = relativeGroups.some(relativeGroup => group?.dependsOn?.id === relativeGroup.groupId)
return hasDependingGroups || hasRelativeGroups
});

How to delete a voice channel when everybody disconnects?

I created a join to create system that creates a channel when a user join and delete it when they leave. However, it only deletes if the last person that's leaving is the user who created the room. Any ideas?
const { Collection } = require("discord.js");
const voiceCollection = new Collection();
module.exports = async (Discord, client, oldState, newState) => {
const user = await client.users.fetch(newState.id);
const member = newState.guild.member(user);
// JOIN
if (!voiceName || voiceName === "") {
if (!oldState.channel && newState.channelID === "898245212541976667") {
const channel = await newState.guild.channels.create(user.tag, {
type: "voice",
parent: newState.channel.parent,
});
member.voice.setChannel(channel);
voiceCollection.set(user.id, channel.id);
await channel.overwritePermissions([
{
id: user.id,
allow: ["MANAGE_CHANNELS", "CONNECT"],
},
{
id: member.guild.id,
deny: ["CONNECT"],
},
]);
} else if (!newState.channel) {
if (oldState.channelID === voiceCollection.get(newState.id)) {
if (oldState.channel.members.size < 1) {
return oldState.channel.delete();
}
}
}
var newchannel_id = config.Channel_id;
var category_id = config.category;
var userchannellist = []
client.login(token);
client.on('voiceStateUpdate', async (oldMember, newMember) => {
if (newMember.channel !== null && oldMember.channel === null && newMember.channel.id === newchannel_id || newMember.channel !== null && oldMember.channel !== null && newMember.channel.id === newchannel_id) {
var current_user = newMember.member.user;
console.log(current_user.username + 'creating the channel');
// Start the creation of the new channel
var server = newMember.guild;
let USERA = newMember.member.nickname || newMember.member.user.username;
var channel = {
type: 'voice', bitrate: 384000, parent: category_id, permissionOverwrites: [{
// permissions
id: server.id, allow: ['VIEW_CHANNEL'],
},
{
id: current_user.id, allow: ['MOVE_MEMBERS', 'MANAGE_CHANNELS']
}
]
};
server.channels.create('🔊' + USERA, channel).then(channel => {
newMember.setChannel(channel).catch(console.error)
userchannellist.push(channel)
//channel region
client.api.channels(channel.id).patch({ data: { rtc_region: "rotterdam" } })
}).catch(console.error);
}
// delete Chaneel
if (oldMember.channel) {
let filter = (ch) =>
(ch.parentID == category_id)
&& (ch.id !== newchannel_id)
&& (oldMember.channel == ch.id)
&& (oldMember.channel.members.size == 0);
return oldMember.guild.channels.cache
.filter(filter)
.forEach((ch) => ch.delete()
.catch(console.error));
}
});

Is there a better way to achieve this?

I am using React. On click of a button, the following function is executed:
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const updatedData = [...prevData];
const updatedItem = updatedData.filter((ele) => ele.id === idValue)[0];
updatedItem.completed = true;
const newData = updatedData.filter((ele) => ele !== updatedItem);
newData.unshift(updatedItem);
return newData;
});
};
My data is an array of objects like this:
[{userId: 1, id: 2, title: "task 1", completed: true}, .....].
Basically I want to move the updated item to the start of the array. Is there any better solution for this?
updatedItem should not be mutated. And this string const newData = updatedData.filter((ele) => ele !== updatedItem); is not fine. You can do it like this :
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const targetItem = prevData.find((ele) => ele.id === idValue);
const updatedItem = { ...targetItem, completed: true };
const filteredData = prevData.filter((ele) => ele.id !== idValue);
return [updatedItem, ...filteredData];
});
};
Even better to reducing an extra filter:
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const targetIndex = prevData.findIndex((ele) => ele.id === idValue);
return [{ ...prevData[targetIndex], completed: true }].concat(prevData.slice(0, targetIndex + 1)) .concat(
prevData.slice(targetIndex + 1)
)
});
};
First find index of updated element using Array.findIndex(), then remove the same element using Array.splice() and add it to front of the array.
const completeTaskHandler = (idValue) => {
setData((prevData) => {
const updatedData = [...prevData];
const index = updatedData.findIndex(obj => obj.id === idValue);
const [updatedItem] = updatedData.splice(index, 1);
updatedItem.completed = true;
updatedData.unshift(updatedItem);
return updatedData;
});
};
The simplest one with only one forEach.
const completeTaskHandler = idValue => {
setData(prevData => {
let updatedItem = {}, newData = [];
prevData.forEach((ele) => {
if (ele.id === idValue) {
updatedItem = ele;
updatedItem.completed = true;
} else {
newData.push(ele);
}
});
newData.unshift(updatedItem);
return newData;
});
};

React : Need a faster way to filter data and setState

I need to make a menu list for a restaurant app, and the menu data is categorized in American, Chinese, Indian, Italian. I need to loop over all these to render it somehow in the scrollspy type menu.
For that I have configured the backend to send in ALL the ITEMS at once and need to filter and sort it as per the category on the react side.
DATA STRUCTURE :
{
_id: 5eef61450bd95e1f5c8f372f
name: "Burger"
category: "American"
price: "100"
isVeg: false
__v: 0
}
The way i am doing is seems too slow and I believe there is GOT TO BE A FASTER/EFFECIENT WAY. Please suggest, because my way makes me want to puke.
const CheckForms = () => {
const [american, setAmerican] = useState([]);
const [italian, setItalian] = useState([]);
const [indian, setIndian] = useState([]);
const [chinese, setChinese] = useState([]);
const fetchList = async () => {
try {
const res = await axios.get(`http://localhost:5000/api/items`);
const list = res.data.response;
let ch = [];
let ind = [];
let am = [];
let it = [];
list.forEach(function(each){
if (each.category === "Chinese") ch.push(each)
else if (each.category === "Indian") ind.push(each)
else if (each.category === "American") am.push(each)
else if (each.category === "Italian") it.push(each)
else console.log('undefined category');
});
setAmerican(am);
setIndian(ind);
setChinese(ch);
setItalian(it);
} catch (err) {
console.log(err.response);
};
};
useEffect(()=> {
fetchList();
}, []);
let render;
if (indian.length > 0 && american.length > 0 && chinese.length > 0 && italian.length > 0) {
render = (
/*********************************
* AND FURTHER RENDERING LOGIC :(
********************************/
);
};
You could try reduce:
const list = [
{ category: 'Chinese', name: 'one-1' },
{ category: 'Chinese', name: 'one-2' },
{ category: 'Indian', name: 'two' },
];
const groups = list.reduce(
(result, item) =>
result.set(
item.category,
(result.get(item.category) || []).concat(item)
),
new Map()
);
console.log('Chinese',groups.get('Chinese'));
console.log('Indian',groups.get('Indian'));

Why does my function always return undefined?

I have written a function to search in a nested object. The problem is that it returns undefined instead of the expected result, that is correctly logged in the console. Whats going on there?
const in1 = [1, 2];
const in2 = [1, 2];
const vDOM = {
1: {
ref: in1,
children: {
2: {
ref: in2,
children: {}
}
}
}
}
const findVDOMNode = function(instance, vDOM) {
const keys = Object.keys(vDOM);
const foundKey = keys.find(key => vDOM[key].ref === instance);
//console.log(foundKey, vDOM, "FK");
if (!keys.length) {
console.log('no keys');
return;
}
if (foundKey) {
console.log('found', vDOM[foundKey]);
return true; //vDOM[foundKey];
};
keys.map(key =>
findVDOMNode(instance, vDOM[key].children));
}
console.log('res: ', findVDOMNode(in2, vDOM));
Live example: https://stackblitz.com/edit/js-dapzsy
Just add return at the end.
return keys.map(key =>
findVDOMNode(instance, vDOM[key].children));
You could take the values of the object and check it against the instance. If an object is found, check the object as well. For iterating use some with short circuit, if the instance is found.
const
in1 = [1, 2],
in2 = [1, 2],
vDOM = { 1: { ref: in1, children: { 2: { ref: in2, children: {} } } } },
findVDOMNode = (instance, vDOM) => Object
.values(vDOM)
.some(v => v === instance
|| v && typeof v === 'object' && findVDOMNode(instance, v)
);
console.log('res: ', findVDOMNode(in2, vDOM));
it looks like you are missing a return statement on the map in the last line of the function
const in1 = [1, 2];
const in2 = [1, 2];
const vDOM = {
1: {
ref: in1,
children: {
2: {
ref: in2,
children: {}
}
}
}
}
const findVDOMNode = function(instance, vDOM) {
const keys = Object.keys(vDOM);
const foundKey = keys.find(key => vDOM[key].ref === instance);
//console.log(foundKey, vDOM, "FK");
if (!keys.length) {
console.log('no keys');
return;
}
if (foundKey) {
console.log('found', vDOM[foundKey]);
return true; //vDOM[foundKey];
};
///added this return statement
return keys.map(key =>
findVDOMNode(instance, vDOM[key].children));
}
console.log('res: ', findVDOMNode(in2, vDOM));

Categories

Resources