I am creating an object inside a function. Now I want to access the value of the object and print it out to the console.
const pattern = /^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
function isEmailAddress(str) {
return str.match(pattern);
}
let signUpFormValidation = (formData) => {
const error = {};
const fields = ['email', 'password', 'name'];
fields.forEach(field => {
if (!formData[`${field}`]) {
error[[field]] = `${field} not present`;
}
})
if (formData.name && (formData.name.length < 3 || formData.name.length > 20)) {
error['name'] = 'Name should be atleast 4 chars and less than 20 chars';
}
if (formData.password && (formData.password.length < 6 || formData.password.length > 30)) {
error['password'] = 'Password should be atleast 6 chars and less than 30 chars';
}
if (formData.email && isEmailAddress(formData.email) === null) {
error['email'] = 'Not a valid email';
}
if (Object.keys(error).length === 0) return null;
return error;
}
I am 'Name should be at least 4 chars and less than 20 chars' in console. How I get it.
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 months ago.
Console log inside if block prints but return value is empty, why ? i have create let emailHtml varaible to whom i am assigning value in the block
cy.request('GET', `https://api.testmail.app/api/json?apikey=${APIKEY}&namespace=${NAMESPACE}&tag=dev`).then(
(response) => {
if (response.body.emails.length != 0) {
response.body.emails.forEach((email: any) => {
if (email.subject === subject) {
emailHtml = email.html;
console.log(emailHtml); // prints
}
});
}
if (response.body.emails.length === 0) {
cy.wait(3000);
TestMailService.getLatestEmail(subject, ++attempts);
}
},
);
console.log(emailHtml); // empty
return emailHtml;
}
My solution that might help others
export class TestMailService {
static async getLatestEmailBySubject(subject: string) {
let emailAsHtml: string = '';
const NAMESPACE: string = '';
const APIKEY: string = '';
let emailSentTimeStamp: string = Math.round(Date.now() - 120000).toString();
for (let i = 0; i <= 40; i++) {
const response: Inbox = await new Cypress.Promise((resolve, reject) => {
cy.request<Inbox>(
'GET',
`https://api.testmail.app/api/json?apikey=${APIKEY}&namespace=${NAMESPACE}&tag=testnow2×tamp_from=${emailSentTimeStamp}`,
).then((response: Inbox) => {
resolve(response);
reject('bad request');
});
});
if (response.body.emails.length === 0) {
cy.wait(3000);
} else if (
response.body.emails.length > 0 &&
response.body.emails[0].subject === subject &&
response.body.emails[0].timestamp > emailSentTimeStamp
) {
emailAsHtml = response.body.emails[0].html;
break;
}
}
return emailAsHtml;
}
}
Here are two variables whose values are unexpected for me I can't get a way around it. Whenever I try to push message object in array inside a loop even after the variable being in global scope of the loop the value of variable currentUsersMessages is an empty array, similarly targetUserName is returning undefined however I can access value inside the callback function.
let AccountsCollection = require('../models/account')
let {PrivateChat} = require('../models/chat.model')
let messageFetchingLimit = 10;
function standardMessage(message){
let developedMessage = {
content : message.content,
content_received : message.content_received,
content_seen : message.content_seen,
sending_user : message.sending_user,
receiving_user : message.receiving_user,
delivery_date : message.delivery_date,
delivery_time : message.delivery_time,
}
if(message.attachment !== undefined){
developedMessage.attachment_url = `http://localhost:5000/chats/media/${message.attachment.file_name}`
developedMessage.attachment_type = message.attachment.file_type
}
return developedMessage;
}
router.get('/' , (req, res) => {
let targetUserName;
// Here We Will Find Target User Name to whom the logged in user is talking
AccountsCollection.findOne({identifier : {publicKey : req.query.targetUserPublicKey}} , (err,success) => {
if(success){
targetUserName = success.name
}
else {
return null;
}
})
// Here we will find and send previous chats of these chatting users
const previousChats = []
let currentUserMessages = []
PrivateChat.findOne({ $and : [{'template.users' :{$in : req.query.userPublicKey}} , {'template.users' : {$in : req.query.targetUserPublicKey}}]}, async (err,usersChatObject) => {
if (usersChatObject) {
const userPreviousChats = usersChatObject.template.messages
let previousMessageCount = parseInt(req.query.nfmr)
if(userPreviousChats.length > 0){
//? IF Messages Are Less Than 10
if((userPreviousChats.length - previousMessageCount) <= messageFetchingLimit ){
console.log('messages are less than 10')
for(let index = userPreviousChats.length - (previousMessageCount + 1) ; index >= 0; index--){
let message = await standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
console.log(message)
}
console.log(currentUserMessages)
}
//? IF Messages are not available
else if (userPreviousChats.length < 1 || userPreviousChats.length == -1){
res.json({messageCount : 0})
}
//? Otherwise if Messages are available and more than or equals to 10
else {
let numberOfMessages = userPreviousChats.length - 1
let messageLeftToShow = numberOfMessages - previousMessageCount
if(messageLeftToShow <= 10){
for (let index = messageLeftToShow; index >= 0; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
else {
// If messages are more than 10
console.log(messageLeftToShow - 10);
for (let index = messageLeftToShow; index > messageLeftToShow - 10; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
}
previousChats.push({
userPublicKey : req.query.userPublicKey,
targetUserPublicKey : req.query.targetUserPublicKey,
targetName : targetUserName,
serverSentMessageCount : `${previousMessageCount + (currentUserMessages.length)}`,
messages : currentUserMessages
})
console.log(previousChats)
res.json(previousChats)
}
else {
res.json({error : "No Previous Messages Are Available"})
}
}
else {
console.log(err);
res.status(404).json({ error: 'Messages Record Is Not Available'})
}
})
})
The problem here are that both AccountsCollection.findOne and PrivateChat.findOne are asyncronous
it's easier if you handle it with async/await instead of callback like this
let AccountsCollection = require('../models/account')
let {
PrivateChat
} = require('../models/chat.model')
let messageFetchingLimit = 10;
router.get('/', async(req, res) => {
let targetUserName;
// Here We Will Find Target User Name to whom the logged in user is talking
try {
targetUserName = await AccountsCollection.findOne({
identifier: {
publicKey: req.query.targetUserPublicKey
}
})
} catch (e) {
targetUsername = null
}
// Here we will find and send previous chats of these chatting users
const previousChats = []
let currentUserMessages = []
try {
const userChatObject = await PrivateChat.findOne({
$and: [{
'template.users': {
$in: req.query.userPublicKey
}
}, {
'template.users': {
$in: req.query.targetUserPublicKey
}
}]
})
const userPreviousChats = usersChatObject.template.messages
let previousMessageCount = parseInt(req.query.nfmr)
if (userPreviousChats.length > 0) {
//? IF Messages Are Less Than 10
if ((userPreviousChats.length - previousMessageCount) <= messageFetchingLimit) {
console.log('messages are less than 10')
for (let index = userPreviousChats.length - (previousMessageCount + 1); index >= 0; index--) {
let message = await standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
console.log(message)
}
console.log(currentUserMessages)
}
//? IF Messages are not available
else if (userPreviousChats.length < 1 || userPreviousChats.length == -1) {
res.json({
messageCount: 0
})
return;
}
//? Otherwise if Messages are available and more than or equals to 10
else {
let numberOfMessages = userPreviousChats.length - 1
let messageLeftToShow = numberOfMessages - previousMessageCount
if (messageLeftToShow <= 10) {
for (let index = messageLeftToShow; index >= 0; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
} else {
// If messages are more than 10
console.log(messageLeftToShow - 10);
for (let index = messageLeftToShow; index > messageLeftToShow - 10; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
}
previousChats.push({
userPublicKey: req.query.userPublicKey,
targetUserPublicKey: req.query.targetUserPublicKey,
targetName: targetUserName,
serverSentMessageCount: `${previousMessageCount + (currentUserMessages.length)}`,
messages: currentUserMessages
})
console.log(previousChats)
res.json(previousChats)
} else {
res.json({
error: "No Previous Messages Are Available"
})
}
} catch (err) {
console.log(err);
res.status(404).json({
error: 'Messages Record Is Not Available'
})
}
})
How can I optimize this
if the string can be split without a 4, 422 and 2222 without a remainder, returns true
tests:
input "4" output "true"(4)
input "44" output "true" (4 4)
input "42" output false(4 2!==2222 || 422 || 4)
input "4224224" output true (422 422 4)
input "42222" output true (4 2222)
input "22224"output true (2222 4)
let solution = (password) => {
if (!password) return false
while (password) {
if (password.includes('2222')) {
while (password.includes('2222')) {
password = password.replace('2222', '')
}
}
if (password.includes('422')) {
while (password.includes('422')) {
password = password.replace('422', '')
}
}
if (password.includes('4')) {
while (password.includes('4')) {
password = password.replace('4', '')
}
}
return !!!password
}
}
console.log(solution('4'));
console.log(solution('44'));
console.log(solution('42'));
console.log(solution('4224224'));
console.log(solution('42222'));
console.log(solution('22224'));
this is the same:
let solution = (password) => {
const searchValue = ['2222', '422', '4']
if (!password) return false
for (let elem = 0, i = searchValue[0]; password; elem++) {
if (password.includes(i)) {
while (password.includes(i)) {
password = password.replace(i, '')
}
}
i = searchValue[elem]
if (elem === 3) {
return !!!password
}
}
return !!!password
}
console.log(solution('4'));
console.log(solution('44'));
console.log(solution('42'));
console.log(solution('4224224'));
console.log(solution('42222'));
console.log(solution('22224'));
Memory limitation on startup - 100 MB
must work with -> const bigStr = new Array(9999999).fill(() =>["4", "422", "2222" ][Math.floor(Math.random() * 3)]).map(f => f()).join('')
Sorry, I forgot to mention that regular expressions are not allowed use
1) You can get the desired result with recursion
const matches = ["4", "2222", "422"];
function isMatch(str) {
if (str.trim() === "") return true;
for (let i = 0; i < matches.length; ++i) {
if (str.startsWith(matches[i])) {
if (isMatch(str.replace(matches[i], ""))) return true;
}
}
return false;
}
console.log(isMatch("4"));
console.log(isMatch("44"));
console.log(isMatch("42"));
console.log(isMatch("4224224"));
console.log(isMatch("42222 "));
console.log(isMatch("2222"));
2) You can use regex here \b(4|2222|422)+\b
const regex = /\b(4|2222|422)+\b/;
function isMatch(str) {
return regex.test(str);
}
console.log(isMatch("4"));
console.log(isMatch("44"));
console.log(isMatch("42"));
console.log(isMatch("4224224"));
console.log(isMatch("42222 "));
console.log(isMatch("2222"));
You can just use replaceAll instead of replacing the string each time and check if it is in there another time:
const bigStr = new Array(9999999).fill(() => ["4", "422", "2222"][Math.floor(Math.random() * 3)]).map(f => f()).join('');
const solution = (password) => {
return password !== "" && !password.replaceAll('2222', '').replaceAll('422', '').replaceAll('4', '');
}
console.log(solution("4"));
console.log(solution("44"));
console.log(solution("42"));
console.log(solution("4224224"));
console.log(solution("42222"));
console.log(solution("2222"));
console.log(solution(bigStr))
I'm trying to validate a form input with multiple hashtags. I absolutely have to split the input and convert it to lowerCase.
ex) #sun #sea #summer #salt #sand
When I'm typing a hashtag that fails the validation, bubble message pops up and tells me it's wrong.
But if I type the next hashtag correctly, previous bubble message clears and the whole validation fails (form can be sent).
I'm assuming it has something to do with .forEach – possibly there are better solutions I'm not yet aware of.
I'm new to JS and would appreciate your answers very much.
// conditions for validation
const hashtagInput = document.querySelector('.text__hashtags');
const commentInput = document.querySelector('.text__description');
const testStartWith = (hashtag) => {
if (!hashtag.startsWith('#')) {
return 'hashtag should start with #';
}
return undefined;
};
const testShortValueLength = (hashtag) => {
if (hashtag.length === 1) {
return 'hashtag should have something after #';
}
return undefined;
};
const testValidity = (hashtag) => {
const regex = /^[A-Za-z0-9]+$/;
const isValid = regex.test(hashtag.split('#')[1]);
if (!isValid) {
return 'hashtag can't have spaces, symbols like #, #, $, etc, or punctuation marks';
}
return undefined;
};
const testLongValueLength = (hashtag) => {
if (hashtag.length > 20) {
return 'maximum hashtag length is 20 symbols';
}
return undefined;
};
const testUniqueName = (hashtagArray, index) => {
if (hashtagArray[index - 1] === hashtagArray[index]) {
return 'the same hashtag can't be used twice';
}
return undefined;
};
const testHashtagQuantity = (hashtagArray) => {
if (hashtagArray.length > 5) {
return 'only 5 hashtags for each photo';
}
return undefined;
};
const testCommentLength = (commentInput) => {
if (commentInput.value.length >= 140) {
return 'maximum comment length is 140 symbols';
}
return undefined;
};
const highlightErrorBackground = (element) => {
element.style.backgroundColor = '#FFDBDB';
};
const whitenBackground = (element) => {
element.style.backgroundColor = 'white';
};
Here is the validation at work
const testHashtagInput = () => {
const hashtagArray = hashtagInput.value.toLowerCase().split(' ');
hashtagArray.forEach((hashtag, index) => {
let error = testStartWith(hashtag)
|| testShortValueLength(hashtag)
|| testValidity(hashtag)
|| testLongValueLength(hashtag)
|| testUniqueName(hashtagArray, index)
|| testHashtagQuantity(hashtagArray);
if (error) {
highlightErrorBackground(hashtagInput);
hashtagInput.setCustomValidity(error);
} else {
whitenBackground(hashtagInput);
hashtagInput.setCustomValidity('');
}
hashtagInput.reportValidity();
});
if (hashtagInput.value === '') {
whitenBackground(hashtagInput);
hashtagInput.setCustomValidity('');
}
hashtagInput.reportValidity();
};
const testCommentInput = () => {
let error = testCommentLength(commentInput);
if (error) {
highlightErrorBackground(commentInput);
commentInput.setCustomValidity(error);
} else {
whitenBackground(commentInput);
commentInput.setCustomValidity('');
}
commentInput.reportValidity();
};
hashtagInput.addEventListener('input', testHashtagInput);
Yes your forEach reevaluates the entire validity of the input based on the individual items but only the last one actually remains in the end because it's the last one being evaluated.
You could change your evaluation to an array-reducer function; best fit for your intention is the reducer "some" (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some).
It iterates over the list of items and returns whether any one (or more) of the items fullfills the criterion formulated in your callback function.
I didn't get to test it now, but I guess this should do it:
let error = hashtagArray.some((hashtag, index) => {
return (testStartWith(hashtag)
|| testShortValueLength(hashtag)
|| testValidity(hashtag)
|| testLongValueLength(hashtag)
|| testUniqueName(hashtagArray, index)
|| testHashtagQuantity(hashtagArray));
});
if (error) {
highlightErrorBackground(hashtagInput);
hashtagInput.setCustomValidity(error);
} else {
whitenBackground(hashtagInput);
hashtagInput.setCustomValidity('');
}
hashtagInput.reportValidity();
HTH, cheers
i try to make a code that if the user not inputing the photo they will get the message "you're not yet inputing the photo" i was using this code to do that
const isEmpty = (value) =>
value === undefined ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0);
module.exports = isEmpty;
and calling them by :
const Validator = require("validator");
const isEmpty = require("./is-empty");
module.exports = validateCreatePost = (data) => {
let errors = {};
data.title = !isEmpty(data.title) ? data.title : "";
data.fieldContent = !isEmpty(data.fieldContent) ? data.fieldContent : "";
data.imageContent = !isEmpty(data.imageContent) ? data.imageContent : "";
data.genreContent = !isEmpty(data.genreContent) ? data.genreContent : "";
if (!Validator.isLength(data.title, { min: 5, max: 256 })) {
errors.title = "Title must be between 5 and 256 characters";
}
if (Validator.isEmpty(data.title)) {
errors.title = "Title field is required";
}
if (!Validator.isLength(data.fieldContent, { min: 100 })) {
errors.fieldContent = "Body field need atleast 100 characters";
}
if (Validator.isEmpty(data.fieldContent)) {
errors.fieldContent = "Body field is required";
}
if (Validator.isEmpty(data.imageContent)) {
errors.imageContent = "Image field is required";
}
if (Validator.isEmpty(data.genreContent)) {
errors.genreContent = "Genre is required";
}
return {
errors,
isValid: isEmpty(errors),
};
};
but whenever i try to input the photo from Postman they always give me this message
Postman Results
i'm stuck to solve this problem.