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.
I created a function to encrypt and decrypt messages. the encrypting works fine. but when I try to log encrypted Hello World! it just logs H.
const chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".split("");
const numbs = "0123456789".split("");
const symbols = "!##$%^&*()_+-=[]{}|;':,./<>?\" ".split("");
function encrypt(message) {
message = message.split("")
var output = []
message.forEach(element => {
if (chars.includes(element)) {
output.push("c" + chars.indexOf(element))
} else if (numbs.includes(element)) {
output.push("n" + numbs.indexOf(element))
} else if (symbols.includes(element)) {
output.push("s" + symbols.indexOf(element))
} else {
console.log(element)
throw new Error(`Unknown character`)
}
});
return output.join("")
}
function decrypt(message) {
message = message.split("");
var output = [];
var prevDeter;
var prevNumbs = [];
message.forEach(element => {
if (element == "c") {
prevDeter = "c"
if (prevNumbs.length > 0) {
output.push(chars[parseInt(prevNumbs.join(""))])
}
} else if (element == "n") {
prevDeter = "n"
if (prevNumbs.length > 0) {
output.push(numbs[parseInt(prevNumbs.join(""))])
}
} else if (element == "s") {
prevDeter = "s"
if (prevNumbs.length > 0) {
output.push(symbols[parseInt(prevNumbs.join(""))])
}
} else {
prevNumbs.push(element)
}
});
return output.join("")
}
//expected to log Hello World! but logs H and when starting the message with a symbol or number it just logs nothing
console.log(decrypt(encrypt("Hello World!")))
Fixed it, i edited the encoding system to place a - between chars and the decoding system to just split the message at - and check if the element starts with c n or s. and then i just used substring to get the number and decrypt it
const chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".split("");
const numbs = "0123456789".split("");
const symbols = "!##$%^&*()_+-=[]{}|;':,./<>?\" ".split("");
function encrypt(message) {
message = message.split("");
var output = [];
message.forEach(element => {
if(chars.includes(element)) {
output.push("-c" + chars.indexOf(element));
}else if(numbs.includes(element)) {
output.push("-n" + numbs.indexOf(element));
}else if(symbols.includes(element)) {
output.push("-s" + symbols.indexOf(element));
}else{
console.log(element);
throw new Error(`Unknown character`);
};
});
return output.join("");
};
function decrypt(message) {
message = message.split("-");
console.log(message)
var output = [];
message.forEach(element => {
if(element.startsWith("c")) {
output.push(chars[element.substring(1)]);
}else if(element.startsWith("n")) {
output.push(numbs[element.substring(1)]);
}else if(element.startsWith("s")) {
output.push(symbols[element.substring(1)]);
}else if(element.length < 1){
}else{
throw new Error(`Invalid message`);
}
});
return output.join("");
};
console.log(decrypt(encrypt("Hello World!")));
You need to split the encoded string based on set/index pairs. This is easy enough to do with a look-ahead regular expression and splitting before a c, n or an s. /(?=[cns])/
const chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".split("");
const numbs = "0123456789".split("");
const symbols = "!##$%^&*()_+-=[]{}|;':,./<>?\" ".split("");
function encrypt(message) {
message = message.split("")
var output = []
message.forEach(element => {
if (chars.includes(element)) {
output.push("c" + chars.indexOf(element))
} else if (numbs.includes(element)) {
output.push("n" + numbs.indexOf(element))
} else if (symbols.includes(element)) {
output.push("s" + symbols.indexOf(element))
} else {
console.log(element)
throw new Error(`Unknown character`)
}
});
return output.join("")
}
function decrypt(message) {
message = message.split(/(?=[cns])/);
var output = [];
message.forEach(element => {
let set;
switch(element[0]){
case 'c':
set = chars;
break;
case 'n':
set = numbs;
break;
case 's':
set = symbols;
break;
}
const index = parseInt(element.substring(1));
output.push(set[index]);
});
return output.join('');
}
const encrypted = encrypt("Hello World!");
console.log(encrypted);
//expected to log Hello World! but logs H and when starting the message with a symbol or number it just logs nothing
console.log(decrypt(encrypted));
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 am trying to create a feature on my website that prints out values in input boxes after an item from the dropdown menu is selected. Currently, my code works, but it is just too lengthy. Below is the JavaScript code that I would like to shorten or stored in a data file.
function dropdownTip(element){
if(element == "Methane") {
document.getElementById("myText").value="190.6";
document.getElementById("myText1").value="45.99";
document.getElementById("myText2").value="0.012";
}
else if(element == "Ethane") {
document.getElementById("myText").value="305.3";
document.getElementById("myText1").value="48.72";
document.getElementById("myText2").value="0.100";
}
else if(element == "Propane") {
document.getElementById("myText").value="369.8";
document.getElementById("myText1").value="48.48";
document.getElementById("myText2").value="0.152";
}
else if(element == "n-Butane") {
document.getElementById("myText").value="425.1";
document.getElementById("myText1").value="37.96";
document.getElementById("myText2").value="0.200";
}
else if(element == "n-Pentane") {
document.getElementById("myText").value="469.7";
document.getElementById("myText1").value="33.70";
document.getElementById("myText2").value="0.252";
}
else if(element == "n-Hexane") {
document.getElementById("myText").value="507.6";
document.getElementById("myText1").value="30.25";
document.getElementById("myText2").value="0.301";
}
else if(element == "n-Heptane") {
document.getElementById("myText").value="540.2";
document.getElementById("myText1").value="27.40";
document.getElementById("myText2").value="0.350";
}
else if(element == "n-Octane") {
document.getElementById("myText").value="568.7";
document.getElementById("myText1").value="24.90";
document.getElementById("myText2").value="0.400";
}
else if(element == "n-Nonane") {
document.getElementById("myText").value="594.6";
document.getElementById("myText1").value="22.90";
document.getElementById("myText2").value="0.444";
}
else if(element == "n-Decane") {
document.getElementById("myText").value="617.7";
document.getElementById("myText1").value="21.10";
document.getElementById("myText2").value="0.492";
}
The code is actually way longer than this. The else if(element== "x") {} lines actually extend for another 390 lines.
You can add the values in a array of objects and use it something like this obj[element]['text']
var obj = {
"methane" : {"text":"190.6","text1":"45.99","text2":"0.012"},
"eethane" : {"text":"305.3","text1":"48.72","text2":"0.100"}
}
function dropdownTip(element){
if(element) {
console.log(obj[element]['text'],obj[element]['text1'],obj[element]['text2']);
/*document.getElementById("myText").value=obj[element]['text'];
document.getElementById("myText1").value=obj[element]['text1'];
document.getElementById("myText2").value=obj[element]['text2'];*/
}
}
dropdownTip("methane")
I'd use an object indexed by element, whose values are arrays of #myText, #myText1, #myText2 values:
const elementValues = {
Methane: [190.6, 45.99, 0.012],
Ethane: [305.3, 48.72, '0.100'], // you'll need to use strings for trailing zeros
Propane: [369.8, 48.48, 0.152],
'n-Butane': [425.1, 37.96, '0.200'],
// ...
}
function dropdownTip(element){
const possibleArr = elementValues[element];
if (possibleArr) {
['myText', 'myText1', 'myText2'].forEach(
(id, i) => document.getElementById(id).value = possibleArr[i]
);
}
}
You might consider using classes instead of IDs, which would make the code a bit simpler:
const elementValues = {
Methane: [190.6, 45.99, 0.012],
Ethane: [305.3, 48.72, '0.100'], // you'll need to use strings for trailing zeros
Propane: [369.8, 48.48, 0.152],
'n-Butane': [425.1, 37.96, '0.200'],
// ...
}
function dropdownTip(element){
const possibleArr = elementValues[element];
if (possibleArr) {
document.querySelectorAll('.myText').forEach((elm, i) => {
elm.value = possibleArr[i];
});
}
}
const elementValues = {
Methane: [190.6, 45.99, 0.012],
Ethane: [305.3, 48.72, '0.100'], // you'll need to use strings for trailing zeros
Propane: [369.8, 48.48, 0.152],
'n-Butane': [425.1, 37.96, '0.200'],
// ...
}
function dropdownTip(element){
const possibleArr = elementValues[element];
if (possibleArr) {
document.querySelectorAll('.myText').forEach((elm, i) => {
elm.value = possibleArr[i];
});
}
}
<input onchange="dropdownTip(this.value)">
<br>
<input class="myText"></div>
<input class="myText"></div>
<input class="myText"></div>
If you don't like the bracket notation, another option is to write a long multiline string, which you transform into an object afterwards:
const elementValuesStr = `
Methane 190.6 45.99 0.012
Ethane 305.3 48.72, 0.100
Propane 369.8 48.48 0.152
n-Butane 425.1 37.96, 0.200
...
`;
const elementValues = elementValuesStr
.trim()
.split('\n')
.reduce((a, line) => {
const [key, ...vals] = line.match(/\S+/g);
a[key] = vals;
return a;
}, {});
And then you can use the same code as above, using elementValues.
const elementValuesStr = `
Methane 190.6 45.99 0.012
Ethane 305.3 48.72, 0.100
Propane 369.8 48.48 0.152
n-Butane 425.1 37.96, 0.200
`;
const elementValues = elementValuesStr
.trim()
.split('\n')
.reduce((a, line) => {
const [key, ...vals] = line.match(/\S+/g);
a[key] = vals;
return a;
}, {});
console.log(elementValues);
I am trying to filter letter by letter on an array as below
MyJSON
"mainArr":[
{
"data":false,
"myArr":[
{
"myNumber": 12345,
},
{
"myNumber": 8961,
}
]
}
]
And here is code which I am drafting below for search but unable to pick object based on letter keypress or key down or ion-input
if (filterVal && filterVal.trim() !== '') {
this.myArray = this.myArray.filter(function (item) {
const results: any = [];
const obj = item.mainArr[0];
if (_.has(obj, 'myArr')) {
console.log(obj.myArr.indexOf(filterVal));
for (let i = 0; i < obj.myArr.length; i++) {
if (obj.myArr.indexOf(filterVal) !== -1)
return results.push(obj.myArr[i]);
}
}
}
});
}
Refered URL
Tried another way of implementing it, but backspace is not re-binding to original array
let results: any = [];
events.subscribe('filterSearch', (filterVal: string) => {
if (filterVal && filterVal.trim() !== '') {
results = Object.assign(this.allEventsSorted.filter(function (item: any): any {
const fltDty = item.mainArr[0];
if (_.has(fltDty, 'myArr')) {
return _.some(
item.mainArr[0].myArr,
function (tag): any {
return _.startsWith(tag.myNumber, filterVal);
// return _.includes(tag.myNumber, filterVal);
}
);
}
}));
this.allEventsSorted = results;
}
});