I am creating a login system and i want to implement a username system automatically after registration with the user first-name and last-name. Everything is working fine but in the case if the registered user with the same first-name and last-name is already in the system i want to concatenate a incrmental number to it.
Example if : firstname:Badmus Lastname:Kabiru is in the system as badmus.kabiru and the newly registered user is also named so the new user username will be badmus.kabiru.1 the next will be badmus.kabiru.2.
My code sample are.
assignUserTrendname: function(req_username, callback){
let userNewname = fetchUserName(req_username);
let inc = 1, newlyAssignUsername;
userNewname.then((usernames) => {
console.log(req_username+" ...................... "+usernames); //The data from the database is loging out
if (usernames.atusername == null || usernames.atusername == undefined) {
newlyAssignUsername = req_username;
console.log("Assign automaticaly "+ newlyAssignUsername);
} else {
newlyAssignUsername = req_username;
console.log(`Username Result is DB: ${usernames.atusername} Req: ${newlyAssignUsername} Search ${inc}`);
if(usernames.atusername.toString() == newlyAssignUsername.toString()){
console.log("User name exit and inc is "+ inc);
inc++;
newlyAssignUsername = `${req_username}.${inc}`;
console.log("New search..."+ newlyAssignUsername);
fetchusernames(newlyAssignUsername); // These is not fetching from the database
}
newlyAssignUsername = `${req_username}.${inc}`;
}
console.log("Assigned is ......"+ newTrendname);
callback(null, newTrendname);
})
.catch((err)=> {console.log(err); throw err;});
}
function fetchUserName(trendname){
return Trender.getUserByTrendname(trendname);
}
If i am taking the wrong route please let me know.
Thanks.
In the scenario that your.username already exists you can search your Users with a regex pattern: ((?:your\.username)\d+$). This will get all records that match: your.username{num} where {num} is any number. If your username's are formatted as your.username.123 the pattern would be: ((?:your\.username\.)\d+$).
Assuming this returns an array, existing_users, you can count the records, since you'll always be incrementing by one, which will give you your next incremented number. Pseudo code:
let inc = existing_users.length + 1;
However, in the scenario that you delete a user your count is going to be off. You would need to loop over your existing_users and extract the number at the end and only keep the largest number.
let largest_num = 0;
existing_users.forEach(user => {
let num = user.match(/\d+$/);
if ( num != null && parseInt(num[0]) > largest_num ) {
largest_num = num[0];
}
});
Then you could do the same as above: let inc = largest_num + 1 and add that to your your.username string.
I do not know what library/framework you're using to search your MongoDB so I cannot write a query and function snippet.
We cannot write your code for you. A general regex has already been given that could be a potential way to solve your problem. If you go that route you can make use of the $regex operator. If you were to store the increment of the username as a separate field you could also sort by that to get the max value as well.
Here is an example of that:
db.users.find({
username: {
$regex: < Your Regex Here >
}
}).sort({
usernameIncrement: -1
}).limit(1);
Please see:
http://mongoosejs.com/docs/queries.html
https://docs.mongodb.com/manual/reference/operator/query/regex/
https://docs.mongodb.com/manual/reference/method/cursor.sort/
Related
I have been trying to figure out how have a form submit which then checks all the data in the form against JSON array data to determine if an object which matches all the input is already present. To start, here is my sample JSON data:
[
{
"ASIN":"B0971Y6PQ3",
"price":"13.99",
"email": "test#gmail.com"
},
{
"ASIN":"B077TLGP58",
"price":"13.99",
"email":"test#gmail.com"
}
]
So I am trying to run a for loop which will test whether all the form data already exists as a JSON object. Here's what I currently have:
// Check to see if it's already in asinJSON.json
for(i=0; i<asinJSON.length;i++){
if(asinJSON[i].email == email){
// Email is already in json
if(asinJSON[i].ASIN == inputVal){
// Email && ASIN are already in json
if(asinJSON[i].price == desiredPrice){
// Email, ASIN, Price all match. Duplicate.
console.log('same price found. product already exists.');
break;
}
// If price doesn't match, user wants to update price
console.log('updating price');
// Update price here
// updateJSON();
break;
}
// Existing user wants to add new product.
console.log('product not found');
// Insert product for existing user
// createAndAdd();
break;
}
// New user wants to add a product.
console.log('email not found.');
// insert product for new user
// createAndAdd();
break;
}
How it is now, when trying to test whether it can find the second object, it console.logs "product not found," which I understand is because it passes the first if statement but fails the second with the 1st object in the JSON array.
I'm also assuming it has to do with my break statements, and that something is wrong there. I've also tried return statents and haven't been able to figure it out. I've been self-taught so there are, unfortunately, some things that I have definitely missed along the way. But, I have looked aroung Google and StackOverflow and haven't really been able to find an answer, so here I am.
I'm ready to be schooled in how this logic should be set up to get it to work properly. I appreciate all the feedback in advance!
Use the find() method to search for a matching element.
if (asinJSON.find(({ASIN, price, email: json_email}) =>
ASIN == inputVal && price == desiredPrice && json_email == email)) {
console.log("product already exists");
} else {
console.log("product not found");
}
There are many options, one easy one is to use lodash
const email = <email to find>
const price = <price to find> (however, keep your mind around floating points comparison here...)
const ASIN = < ASIN to find >
if (findIndex(asinJSON, { ASIN, price, email }) > -1) {
// found
}
I am not very efficient with my code which may be the reasons why this keeps failing. I am trying to remove and assign roles to "verified" users. The basic gist of the code is to loop through all "verified" users and assign them appropriate roles according to the data received from the API.
const fetch = require("node-fetch");
var i = 0;
function mainLoop(
guild,
redisClient,
users,
main_list,
Pilot,
Astronaut,
Cadet,
main_guild,
cadet_guild,
guest
) {
setTimeout(function () {
redisClient.GET(users[i], async function (err, reply) {
if (reply != null) {
var json = await JSON.parse(reply);
var uuid = Object.keys(json).shift();
if (Object.keys(main_list).includes(uuid)) {
var tag = users.shift();
var rank = main_list[uuid];
console.log(`${tag}: ${rank}`);
var role = guild.roles.cache.find(
(role) => role.name === `| ✧ | ${rank} | ✧ |`
);
await guild.members.cache.get(tag).roles.remove(guest);
await guild.members.cache.get(tag).roles.remove(Astronaut);
await guild.members.cache.get(tag).roles.remove(Cadet);
await guild.members.cache.get(tag).roles.remove(Pilot);
await guild.members.cache.get(tag).roles.remove(cadet_guild);
await guild.members.cache.get(tag).roles.add(main_guild);
await guild.members.cache.get(tag).roles.add(role);
} else {
var tag = users.shift();
console.log(`${tag}: Guest`);
await guild.members.cache.get(tag).roles.remove(Astronaut);
await guild.members.cache.get(tag).roles.remove(Cadet);
await guild.members.cache.get(tag).roles.remove(Pilot);
await guild.members.cache.get(tag).roles.remove(main_guild);
await guild.members.cache.get(tag).roles.remove(cadet_guild);
await guild.members.cache.get(tag).roles.add(guest);
}
}
i++;
if (i < users.length) {
mainLoop(
guild,
redisClient,
users,
main_list,
Pilot,
Astronaut,
Cadet,
main_guild,
cadet_guild,
guest
);
}
});
}, 5000);
}
The code will fetch api data, map the "verified" users and api data into an array. Then, when it starts looping through the users array, it will only log 3 times and not assign any roles. Any help would be appreciated.
I can provide extra explanation/code if needed.
One possible issue I see here is that you are both incrementing the index i and calling .shift() on the users array. This may be the cause of the problem you are experiencing, as this will entirely skip some of the users in the array. Array.shift() doesn't just return the first element of the array; it removes it from the array.
Consider, for example, that your users array looks like this:
var users = ["Ted", "Chris", "Ava", "Madison", "Jay"];
And your index starts at 0 like so:
var i = 0;
This is what is happening in your code:
Assign roles for users[i]; the index is currently 0, so get users[0] (Ted).
Get Ted's tag via users.shift(). users is now: ["Chris", "Ava", "Madison", "Jay"]
Increment the index with i++. i is now: 1.
Assign roles for users[i]; the index is currently 1, so get users[1] (now Ava, skips Chris entirely).
Get Ava's tag via users.shift() (actually gets Chris' tag). users is now: ["Ava", "Madison", "Jay"]
Increment the index with i++. i is now: 2.
Assign roles for users[i]; the index is currently 2, so get users[2] (now Jay, skips Madison entirely).
And so on, for the rest of the array; about half of the users in the users array will be skipped.
I don't know how many users are supposed to be in your users array, but this could be the reason why so few logs are occurring. Note, however, that this is just one cause of the problem you are experiencing; it is possible that there are more reasons why you are having that issue, such as rate limits.
My recommendation on how to fix this is to not use users.shift() to get the user's tag. Simply use users[i], which will return the proper tag value without messing with the length of the array. Another way to fix this would be to remove the index incrementation, and always use 0 as your index. Use one or the other, but not both.
I'm building out a function to handle dynamic phone number swapping, identifying the referral url, mapping through a data set, and then outputting the promoUrl's related phone number. The data is formatted like this:
const phoneNumbers = [
{
promoUrl: '/interior-doors/',
promoNumber: '589-918-0710',
},
{
promoUrl: '/promo4/',
promoNumber: '307-789-8615',
},
];
And the function maps through the data and reduces it, allowing me to sort through it like this:
const url = location.pathname.replace(/\/+$/, '');
const promoNumber = phoneNumbers.reduce((promoNumber, results) => {
const hasPromo = results.promoUrl.includes(url);
if (hasPromo) {
return results.promoNumber;
}
return promoNumber;
}, '');
I'm having some issues with hasPromo. The way it's built right now allows for the promoUrl to have some variance and still work, meaning as long as it includes what is returned from url then it works i.e. /interior-doors/, /interior-doors, and interior-doors will all work, which is great, but it also works if url is /interior-do. I need it to not do that. It should work independent of formatting, but only return the promoNumber if the string of letters is exact.
I'm assuming this is a regex thing, but I don't know what I'm doing with regex. Any help would be greatly appreciated.
Use == to do an exact match. And since the promoURL property always has / around it, add those delimiters when you set url
const url = '/' + location.pathname.replace(/\/+$/, '') + '/';
const promoNumber = phoneNumbers.reduce((promoNumber, results) => {
const hasPromo = results.promoUrl == url;
if (hasPromo) {
return results.promoNumber;
}
return promoNumber;
}, '');
reduce also seems like the wrong function for this. You just need to find the matching promoUrl, you don't have to continue reducing, since the reduction function doesn't merge the results in any way.
const promo = phoneNumbers.find(({promoUrl}) => promoUrl == url);
const promoNumber = promo ? promo.promoNumber : '';
My main goal is for someone with message managing permissions to type a command for deleting a message but be able to specify how many messages they'd like to delete.
I have tried messing with variables but I don't have much knowledge on them, usually ending in some errors. I've tried replacing the value of messages deleted (the 2) with the variable with success but I'm clueless when it comes to changing the variable with a message.
if(message.member.hasPermission('MANAGE_MESSAGES')) {
if(message.content.startsWith(`${prefix}delete`)) {
message.channel.bulkDelete(2)
}
}
I will suppose you have it on message event.
This is one of many ways you can do it:
if(message.content.startsWith(`${prefix}delete`)) {
const user = message.mentions.users.first();
// Parse Amount
const amount = !!parseInt(message.content.split(' ')[1]) ? parseInt(message.content.split(' ')[1]) : parseInt(message.content.split(' ')[2])
//Check if it the amount for message to delete where declared
if (!amount) return message.reply('Must specify an amount to delete!').then(msg => msg.delete(15000));
// Fetch 100 messages (will be filtered and lowered up to max amount requested)
message.channel.fetchMessages({
limit: 100,
}).then((messages) => {
//I declare the messages like that with amount + 1 to delete the command itself
messages = messages.array().slice(0, amount + 1);
//And finally buldDelete deletes the desired amount
message.channel.bulkDelete(messages).then(messages => console.log(`Bulk deleted ${args[0]} messages`))
.catch(console.error);
});
You would need to split message.content, which will return an array that I'll name args for this example. Then, args[1] should be the number you are looking for.
const prefix = '#'
const args = message.content.split(' ')
if(message.member.hasPermission('MANAGE_MESSAGES')) {
if(message.content.startsWith(`${prefix}delete`)) {
message.channel.bulkDelete(args[1])
}
}
Et voilà ! You just need to make sure that args[1] is a number now.
Using the newest version of Postman.
I have a predefined variable "useridToken" which is a number: 123456
var useridToken = pm.environment.get("useridToken");
//console.log(useridToken);
var jsonData = pm.response.json();
const user = jsonData.find(u => u.user_metadata.employeeId === useridToken);
const userid = user ? user.user_id : 'not found';
pm.environment.set("user_id", userid);
Whenever I run this code, it returns errors.
The console log output is the number as an integer: 123456
Whenever I run the following code:
var useridToken = 123456
var jsonData = pm.response.json();
const user = jsonData.find(u => u.user_metadata.employeeId === useridToken);
const userid = user ? user.user_id : 'not found';
pm.environment.set("user_id", userid);
It works like a charm, but I don't want the hardcoded useridToken in my code, I would like to get it from my environment variables. I don't quite understand why the first part isn't working? What am I overseeing?
This is happening because in your .find method you're using === comparison, and when you fetch from environment you always get it as a 'string' and not a 'number' (Postman always gives the value of the environment variable in the string format)
So when you use a === comparison in JS, it also checks the type of the data, here
string === number will actually be false and that's why your find doesn't work.
So, you need to update your code to actually parse the integer that you got from the environment.
This should fix your issue:
var useridToken = parseInt(pm.environment.get("useridToken"));
SOLUTION:
Since you are using === operator, it checks for the type of the variables too. The type for both operands might be different on certain scenarios. So, use the following to avoid the issue.
const user = jsonData.find(u => +u.user_metadata.employeeId === +useridToken); // converts to number then checks
or
const user = jsonData.find(u => u.user_metadata.employeeId.toString() === useridToken.toString()); // converts to string then checks
or
const user = jsonData.find(u => u.user_metadata.employeeId == useridToken); // checks without the operands type. (not recommended)