reducing the If else condtion code in javascript - javascript

I wrote a code to fetch the data present and store it in Array format but I thing I have wrote code multiple times can It be possible to minimize the code as its too long
let topicsValue = ["requiredType.*", "Entry.*", "token.*", "RestAPI.*"];
let Topic = [],
rest = ["required", "unrequired"],
final = ["createInput", "mustPossible", "finalOutput"];
topicsValue.map((data) => {
let requiredType, entries, token, restAPI;
if (data.split(".")[1].includes("*")) {
if (data.split(".")[0].includes("requiredType")) {
for (const value of final) {
requiredType = data
.split(".")[0]
.replace("requiredType", "required_type")
.concat(`.${value}`);
Topic.push(requiredType);
}
}
if (data.split(".")[0].includes("Entry")) {
for (const value of final) {
entries = data
.split(".")[0]
.replace("Entry", "entries")
.concat(`.${value}`);
Topic.push(entries);
}
for (const value of rest) {
entries = data
.split(".")[0]
.replace("Entry", "entries")
.concat(`.${value}`);
Topic.push(entries);
}
}
if (data.split(".")[0].includes("token")) {
for (const value of final) {
token = data
.split(".")[0]
.replace("token", "tokens")
.concat(`.${value}`);
Topic.push(token);
}
for (const value of rest) {
token = data
.split(".")[0]
.replace("token", "tokens")
.concat(`.${value}`);
Topic.push(token);
}
}
if (
data.split(".")[0].includes("RestAPI") &&
!data.split(".")[0].includes("RestAPIAction")
) {
restAPI = data
.split(".")[0]
.replace("RestAPI", "restAPI")
.concat(`.deploy`);
Topic.push(restAPI);
}
} else {
if (data.split(".")[0].includes("requiredType")) {
if (!rest.includes(data.split(".")[1])) {
requiredType = data
.split(".")[0]
.replace("requiredType", "required_type")
.concat(`.${data.split(".")[1]}`);
Topic.push(requiredType);
}
}
if (data.split(".")[0].includes("Entry")) {
if (rest.includes(data.split(".")[1])) {
entries = data
.split(".")[0]
.replace("Entry", "entries")
.concat(`.${data.split(".")[1]}.demo`);
Topic.push(entries);
} else {
entries = data
.split(".")[0]
.replace("Entry", "entries")
.concat(`.${data.split(".")[1]}.demo`);
Topic.push(entries);
}
}
if (data.split(".")[0].includes("token")) {
if (rest.includes(data.split(".")[1])) {
token = data
.split(".")[0]
.replace("token", "tokens")
.concat(`.${data.split(".")[1]}`);
Topic.push(token);
} else {
token = data
.split(".")[0]
.replace("token", "tokens")
.concat(`.${data.split(".")[1]}`);
Topic.push(token);
}
}
if (
data.split(".")[0].includes("RestAPI") &&
!data.split(".")[0].includes("RestAPIAction")
) {
restAPI = data
.split(".")[0]
.replace("RestAPI", "restAPI")
.concat(`.deploy`);
Topic.push(restAPI);
}
}
});
console.log(Topic);
Is there any possible way I can reduce the code without effecting the output
As the requirement of the code is like if the topicValue contain * or the other value so I wrote this long code and now I am trying to minimize the code so its look short and effective.

I made refactoring only if(true) part of your code. You can implement the else part by yourself. I didn't run the code, spend any time for proper naming, etc. So it was quick refactoring to give you an idea. I think there is a mistake in else block because both if and else parts of tokens and Entry are doing the same thing.
let replace = {
requiredType: 'required_type',
Entry: 'entries',
token: 'tokens',
RestAPI: 'restAPI'
}
const run = () => {
topicsValue.map((data) => task(data));
}
const task = (data) => {
data.split(".")[1].includes("*") ? funcIf(data) : funcElse(data);
}
const funcIf = (data) => {
for (const key in replace) {
if (data.split(".")[0].includes(key)) commonTask(key, data);
}
}
const commonTask = (key, data) => {
if (key == 'RestAPI' && data.split(".")[0].includes("RestAPIAction")) return;
final.forEach(value => Topic.push(makeOutput(key, value, data)));
}
const makeOutput = (key, value, data) => {
return data.split(".")[0]
.replace(key, replace[key])
.concat(key == 'restAPI' ? '.deploy' : `.${value}`);
}

Try using the && operator.
if(y==1 && x == 1) {
do somthing
}
it only runs if both statements are true.

Related

People.People.searchDirectoryPeople() query with multiple email addresses

In a Google Apps Script I need to query the Google user profile picture URL of many coworkers.
Here is a working example for a single user:
searchDirectoryPeople('jimmy.neutron#example.com');
function searchDirectoryPeople(query) {
const options = {
query: query,
readMask: 'photos,emailAddresses',
sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE']
}
const people = People.People.searchDirectoryPeople(options);
if(people && people.people) {
Logger.log('size: '+people.people.length);
people.people.forEach(person => {
let url = '';
let email = '';
if(person) {
if(person.photos && person.photos[0]) {
url = person.photos[0].url;
}
if(person.emailAddresses && person.emailAddresses.length) {
person.emailAddresses.forEach(item => {
if(item.metadata && item.metadata.sourcePrimary) {
email = item.value;
}
});
}
}
Logger.log('email: '+email+': '+url);
//Logger.log('person: %s', JSON.stringify(person, null, 2));
});
} else {
Logger.log('no people.people');
}
}
I found out that I can query all jimmy people:
searchDirectoryPeople('jimmy');
I have the email address of all employees. I could loop through a big list of 1000+ employees one by one, but this is not practical. I am looking for a way to query multiple email addresses. The docs at https://developers.google.com/people/api/rest/v1/people/searchDirectoryPeople are cryptic for the query. I tried many things like these but nothing works:
'jimmy.neutron#example.com, carl.wheezer#example.com, cindy.vortex#example.com'
'jimmy.neutron#example.com OR carl.wheezer#example.com OR cindy.vortex#example.com'
I am looking for a query by list of email addresses as input, such as:
[ 'jimmy.neutron#example.com', 'carl.wheezer#example.com', 'cindy.vortex#example.com' ]
Is it possible to have an OR query in People.People.searchDirectoryPeople()?
UPDATE 2022-05-31
I tried looping through all emails and ran either into a quota limit or a script runtime limit.
#Lorena Gomez's answer is correct: First use the People.People.listDirectoryPeople() to get the resource names of all email address, followed by People.People.getBatchGet() to get the profile picture URL by resource names. The former limits to 1000 employees per call, the latter limits to 200. This works in our case where we have 1k+ email addresses as input, and 20k+ employees returned by listDirectoryPeople().
Working code:
const emails = [
'jimmy.neutron#example.com',
'carl.wheezer#example.com',
'cindy.vortex#example.com'
];
let emailToUrl = getGoogleProfilePictureUrls(emails);
Logger.log('emailToUrl: %s', JSON.stringify(emailToUrl, null, 2));
// expected output:
// emailToUrl: {
// "jimmy.neutron#example.com": "https://lh3.googleusercontent.com/a-/xxxx=s100",
// "carl.wheezer#example.com": "https://lh3.googleusercontent.com/a-/xxxx=s100",
// "cindy.vortex#example.com": "https://lh3.googleusercontent.com/a-/xxxx=s100"
// }
function getGoogleProfilePictureUrls(emails) {
let options = {
readMask: 'emailAddresses',
sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE'],
pageSize: 1000
}
let run = 1;
let resourceNameToEmails = {};
let result = {};
while(run === 1 || result.nextPageToken) {
if(result.nextPageToken) {
options.pageToken = result.nextPageToken;
}
result = People.People.listDirectoryPeople(options);
Logger.log('request #' + (run++) + ', got '+result.people.length+' resource names');
result.people.forEach(person => {
if(person.emailAddresses) {
person.emailAddresses.forEach(obj => {
if(obj.metadata && obj.metadata.sourcePrimary) {
let email = obj.value
if(emails.indexOf(email) >= 0) {
resourceNameToEmails[person.resourceName] = email;
}
}
});
}
});
Utilities.sleep(200);
}
run = 1;
let emailToUrl = {};
let resourceNames = Object.keys(resourceNameToEmails);
let resourceNameBatch = resourceNames.splice(0, 200);
while(resourceNameBatch.length) {
options = {
personFields: 'photos',
resourceNames: resourceNameBatch,
sources: [ 'READ_SOURCE_TYPE_PROFILE' ]
};
result = People.People.getBatchGet(options);
if(result && result.responses) {
Logger.log('request #' + (run++) + ', got '+result.responses.length+' urls');
result.responses.forEach(person => {
let primaryUrl = '';
let url = '';
if(person.person && person.person.photos) {
person.person.photos.forEach(photo => {
if(photo.metadata && photo.metadata.source && photo.metadata) {
url = photo.url;
if(photo.metadata.source.type === 'PROFILE' && photo.metadata.primary) {
primaryUrl = url;
}
}
});
}
let email = resourceNameToEmails[person.person.resourceName];
emailToUrl[email] = primaryUrl || url;
});
}
Utilities.sleep(200);
resourceNameBatch = resourceNames.splice(0, 200);
}
return emailToUrl;
}
It looks like with Method: people.searchDirectoryPeople you can only specify one person at a time.
Another option could be People.People.getBatchGet() which will require an extra step but provides you information about a list of the people you specify. The request would look something like this:
const options = {
personFields: 'photos,emailAddresses',
resourceNames: [
'people/account_id',
'people/account_id',
'people/account_id'
],
sources: [
'READ_SOURCE_TYPE_PROFILE'
]
}
const people = People.People.getBatchGet(options);
You can get the user's account_id with Method: people.listDirectoryPeople
How about this?
function searchDirectoryPeople(query) {
const options = {
query: query,
readMask: 'photos,emailAddresses',
sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE']
}
const people = People.People.searchDirectoryPeople(options);
if(people && people.people) {
Logger.log('size: '+people.people.length);
people.people.forEach(person => {
let url = '';
let email = '';
if(person) {
if(person.photos && person.photos[0]) {
url = person.photos[0].url;
}
if(person.emailAddresses && person.emailAddresses.length) {
person.emailAddresses.forEach(item => {
if(item.metadata && item.metadata.sourcePrimary) {
email = item.value;
}
});
}
}
return {"imgurl":url,"email":email}
});
}
}
function searchPlus(emailArray) {
let oA = [];
emailArray.forEach(e => {
oA.push(searchDirectoryPeople(e))
});
if(oA && oA.length) {
return oA;
}
}

Search in the multiply tree view doesn't work properly

have a problem with the implamantation search in the multiple tree view.
Can check the code in the link.
In the group we have childGroup and list, we have to search lists and groups names. (check data in the data.js file)
Think the problem is somewhere here.
const search = (items, term) => {
return items.reduce((acc, item) => {
if (contains(item.name, term)) {
acc.push(item);
} else if (item.childGroupList?.length) {
let newGroupsItems = search(item.childGroupList, term);
if (newGroupsItems?.length) {
item.childGroupList = newGroupsItems;
acc.push(item);
}
} else if (item.list?.length) {
let newListItems = search(item.list, term);
if (newListItems?.length) {
item.list = newListItems;
acc.push(item);
}
}
return acc;
}, []);
};
There were a few issues in your recursive search.
Your if, else if, else if chain should be independent. They should really be three if blocks.
You need to push the result only after when all the searches are done at a certain level. I got a copy of the item and make childGroupList and list properties empty([]) initially and update them when a search is successful.
Try like this.
// main search function, here is the problem
const search = (items, term) => {
return items.reduce((acc, item) => {
let itemCopy = JSON.parse(JSON.stringify(item));
itemCopy.childGroupList = [];
itemCopy.list = [];
let found = false;
if (contains(item.name, term)) {
found = true;
}
if (item.childGroupList?.length) {
let newGroupsItems = search(item.childGroupList, term);
if (newGroupsItems?.length) {
found = true;
itemCopy.childGroupList = newGroupsItems;
}
}
if (item.list?.length) {
let newListItems = search(item.list, term);
if (newListItems?.length) {
found = true;
itemCopy.list = newListItems;
}
}
if (found) {
acc.push(itemCopy);
}
return acc;
}, []);
};
Code sandbox => https://stackblitz.com/edit/react-rmrlj1?file=src%2FApp.js

Discord anti nuke bot whitelist check error

i get error
let executor = await this.members.fetch(executorID);
^^^^^
SyntaxError: await is only valid in async function
when using the code below (use is to check if user breaks any of set filters and if so remove roles or ban user whatever they set option to)
ive tried my best to lable what parts of code does please not english isnt my first language
ive only recieved this error since trying to add a check whitelist feature - everything else works without the whitelist check code
without the code for whitelist the code works and performs as intended and the whitelist code succesfully logs ids for that guild
if(whitelisted && whitelisted.length) {
whitelisted.forEach(x => {
if (executorID === x.user) return;
const { Structures } = require('discord.js');
let whitelisted = db.get(`whitelist_${message.guild.id}`)
const { limits, defaultPrefix } = require('../config.js');
Structures.extend('Guild', Guild => {
class GuildExt extends Guild {
constructor(...args) {
super(...args);
}
get prefix() {
return this.get('prefix', defaultPrefix);
}
get(key, fallback) {
return this.client.db.get(`${this.id}_${key}`) || fallback;
}
set(key, data) {
return this.client.db.set(`${this.id}_${key}`, data);
}
delete(key) {
return this.client.db.delete(`${this.id}_${key}`);
}
resolveChannel(channelID) {
const channel = this.channels.cache.get(channelID);
return channel;
}
get limits() {
var obj = {};
for (var k in limits) {
obj[k] = {
minute: this.get(
`limits.${k}.minute`,
limits[k].per_minute
),
hour: this.get(`limits.${k}.hour`, limits[k].per_hour)
};
}
return obj;
}
getActions(limit = 10, filter = () => true) {
var obj = {};
var l = limits;
for (var k in limits) {
obj[k] = {
name: this.client.Utils.toProperCase(k),
actions: this.client.Utils.convertEntries(
[
...this.get(
this.client.Utils.convertLimitNameToActionType(
k
),
[]
),
...this.get(
`archive.${this.client.Utils.convertLimitNameToActionType(
k
)}`,
[]
)
]
.filter(filter)
.slice(0, limit)
)
};
}
return obj;
}
find_entry(action, filter) {
let guild = this;
return new Promise(resolve => {
(async function search(iter) {
//console.log(`ACTION = ${action} | ITER = ${iter}`);
if (!guild.me) return resolve(null);
if (guild.me.hasPermission('VIEW_AUDIT_LOG')) {
let logs = await guild.fetchAuditLogs({
limit: 10,
type: action
});
let entries = logs.entries;
let entry = null;
entries = entries.filter(filter);
for (var e of entries)
if (!entry || e[0] > entry.id) entry = e[1];
if (entry) return resolve(entry);
}
if (++iter === 5) return resolve(null);
else return setTimeout(search, 200, iter);
})(0);
});
}
push_entry(entry, displayName) {
const action = ['MEMBER_KICK', 'MEMBER_BAN_ADD'].includes(
entry.action
)
? 'MEMBER_REMOVE'
: entry.action;
const oneHourAgo = Date.now() - 1000 * 60 * 60;
// Fetch Entries for a sepcific action (Last Hour)
let entries = this.get(action, []);
// Filter entries older than one hour to a new variable
let olderThanOneHour = entries.filter(
i => !(i.timestamp > oneHourAgo)
);
// Prepend entries older than one hour to the archive
if (olderThanOneHour.length > 0)
this.set(`archive.${action}`, [
...olderThanOneHour,
...this.get(`archive.${action}`, [])
]);
// Filter entries older than one hour from old variable
entries = entries.filter(i => i.timestamp > oneHourAgo);
// Prepend new entry if not already found
if (
!entries.find(
i =>
i.target.id === entry.target.id &&
i.executor.id === entry.executor.id
)
)
entries.unshift({
timestamp: entry.createdTimestamp,
action: entry.action,
target: {
id: entry.target.id,
displayName,
targetType: entry.targetType
},
executor: {
id: entry.executor.id,
displayName: entry.executor.tag
}
});
// Update entries newer than one hour
return this.set(action, entries);
}
async check_limits(entries, executorID, configAction) {
// Ignore if executor is the owner or is whitelisted
if (executorID === this.ownerID) return;
if(whitelisted && whitelisted.length) {
whitelisted.forEach(x => {
if (executorID === x.user) retrun;
// Filter actions relating to executor
const oneMinuteAgo = Date.now() - 1000 * 60;
let executorActionsHour = entries.filter(
i => i.executor.id === executorID
);
let executorActionsMinute = executorActionsHour.filter(
i => i.timestamp > oneMinuteAgo
);
console.log(
`${configAction}/${executorID}: LAST_HOUR: ${executorActionsHour.length} LAST_MINUTE: ${executorActionsMinute.length} `
);
let limits = this.limits;
let limitReached = null;
if (executorActionsHour.length >= limits[configAction].hour)
limitReached = 'Hour';
if (executorActionsMinute.length >= limits[configAction].minute)
limitReached = 'Minute';
// Check if the amount of actions is greater than or equal to the limit
if (limitReached) {
// Remove all of the executor's roles
let executor = await this.members.fetch(executorID);
executor.roles.remove(executor.roles.cache);
// Handle managed roles
let managed = executor.roles.cache
.filter(r => r.managed)
.array();
for (var i = 0; i < managed.length; i++)
managed[i].setPermissions(0, 'Guardian Action');
// Notify owner, executor, and logging channel
const embed = this.client.util
.embed()
.setTitle(`Limit Reached - ${limitReached}`)
.setDescription(
this.client.Utils.convertEntries(
limitReached === 'Hour'
? executorActionsHour
: executorActionsMinute
)
)
.setColor(0x7289da);
await this.owner.send(
embed.setFooter(
"This message was sent to you because you're the Guild owner."
)
);
await executor.send(
embed.setFooter(
'This message was sent to you because you were the executor.'
)
);
const loggingChannel = this.resolveChannel(
this.get(`loggingChannelID`)
);
if (loggingChannel)
await loggingChannel.send(embed.setFooter(''));
}
})
}
}
}
return GuildExt;
});
i am new to JS and any help would be appreciated
please dont hate if i do have bad syntax !!
i am new - sorry if i dont get things the first time
You forgot to make your forEach function async, just change it to:
/* ... */
whitelisted.forEach(async (x) => {
/* ... */
let executor = await this.members.fetch(executorID);
/* ... */
}
/* ... */
Not part of your question but you misspelled return here
if (executorID === x.user) retrun;
Your line
let executor = await this.members.fetch(executorID);
is inside a non-async anonymous function in:
if (whitelisted && whitelisted.length) {
whitelisted.forEach(x => { // <- This line
if (executorID === x.user) return;
// ...
Try changing it with:
if (whitelisted && whitelisted.length) {
whitelisted.forEach(async (x) => { // <- Use async here
if (executorID === x.user) return;
// ...
Also, avoid using forEach to make asynchronous calls.

Mongoose Query FindOne with array

So i want to verify if a value is inside the collection. I've managed to do it using .map. My code looks like this (the field is nested):
const loopFields = [
"nested.field1",
"nested.field2",
"nested.field3",
"nested.field4"
];
async function getField() {
const field = loopFields.map(async (fld, idx) => {
const result = await Field.findOne({ [fld]: req.body.field });
if (result) {
return fld;
}
});
const isFound = await Promise.all(field);
for (i = 0; i < loopFields.length; i++) {
if (isFound[i] !== undefined) {
return true;
}
}
}
const isValid = await getField();
if (!isValid) {
return res.status(400).send("Field not found");
}
The code does work but i'm looking for a way to reffactore it.
build an $or clause dynamically and pass it to the find method like so:
var loopFields = [
"nested.field1",
"nested.field2",
"nested.field3",
"nested.field4"
];
var fields = loopFields.map(field => {
var x = {};
x[field] = req.body.field;
return x;
})
db.collection.find({ $or: fields });

Javascript loop not returning true, when String === String

When looping through an array to find if the array contains a word that I am looking for, the loop always returns 'false' when if I console.log out the what is being compared I can clearly see that the word I am looking for (collectionNameLookingFor) is in the array (collectionNameArray) so it should return true.
function checkCollectionNames(arrayOfCollections, collectionName) {
for (let i = 0; i < arrayofCollections.length; i++) {
if (arrayOfCollections[i] === collectionName) {
return true;
}
}
return false;
}
function saveContentToDb(req, res) {
const db = getDb();
const pageDetails = req.body;
let saveType;
db.db(pageDetails.databaseName).listCollections().toArray((error, collections) => {
if (error) {
throw error;
} else {
collections.map(collection => (collection.name)).forEach(collectionNameArray => {
const collectionNameLookingFor = req.body.page;
const check = checkCollectionNames(collectionNameArray, collectionNameLookingFor);
console.log('===========Looking to see if it is true or false==========');
console.log(check);
console.log(`Name of collection in Database: ${collectionNameArray} ::: ${collectionNameLookingFor}`);
console.log('==========================================================');
if (check === true) {
saveType = 'updated';
console.log(`saveType = ${saveType}`);
} else {
saveType = 'created';
console.log(`saveType = ${saveType}`);
}
});
}
});
}
You might need to check against collectionName, because that is the parameter you hand over, beside arrayOfCollections, instead of the array itself.
function checkCollectionNames(arrayOfCollections, collectionName) {
for (let i = 0; i < arrayOfCollections.length; i++) {
if (arrayOfCollections[i] === collectionName) {
return true;
}
}
return false;
}
Short Version:
function checkCollectionNames(arrayOfCollections, collectionName) {
return arrayOfCollections.includes(collectionName);
}

Categories