Trying to validate email endings in javascript - javascript

Question: I am trying to validate email endings in an array
let input = 'test#gmail.com' // This is grabbed dynamically but for sake of explanation this works the same
let validEndings = ['#gmail.com', '#mail.com', '#aol.com'] //and so on
if(input.endsWith(validEndings)){
console.log('valid')
}else{
console.log('invalid')
}
I can get this to work when validEndings is just a singular string e.g let validEndings = '#gmail.com'
but not when its in an array comparing multiple things

You can solve the problem with regex. Example:
const input = 'test#gmail.com';
const validEndingsRegex = /#gmail.com$|#mail.com$|#aol.com$/g;
const found = input.match(validEndingsRegex);
if (found !== null) {
console.log('valid')
} else {
console.log('invalid')
}

You can achieve this by using Array.some() method which tests whether at least one element in the array passes the test implemented by the provided function. It returns true if, in the array, it finds an element for which the provided function returns true; otherwise it returns false.
Live Demo :
let input = 'test#gmail.com';
let validEndings = ['#gmail.com', '#mail.com', '#aol.com'];
const res = validEndings.some(endingStr => input.endsWith(endingStr));
console.log(res);

Related

Compare user input with csv file, return second column value javascript

I came across the following topic, it just has 1 line instead of 2 columns.
How do I return the second value here (see topic below)
Compare my variable with a csv file and get the matching value in javascript
This is my CSV file values:
csv screenshot of columns
This is what I have currently
IT just checks the file for the serial number from the user and marks the div with text "Valid".
This Valid should have the second Columns value.
<script>
const checkm = document.getElementById('check');
checkm.addEventListener('click', serialChecker)
async function serialChecker(){
const url = 'http://localhost/validator/serials.csv';
const response = await fetch(url);
// wait for the request to be completed
const serialdata = await response.text();
console.log(serialdata);
const inputserialnumber = document.getElementById('serialnumber').value.toString();
console.log(inputserialnumber);
// serialdata.match(/inputserialnumber/)
// serialdata.includes(inputserialnumber)
if(serialdata.includes(inputserialnumber) == true && inputserialnumber.length == 7 ){
document.getElementById('validity').innerHTML = "Valid";
startConfetti(); // from confetti.js
}else {
document.getElementById('validity').innerHTML = "Invalid";
stopConfetti(); // from confetti.js
}
//document.getElementById('test').innerHTML = "Valid";
}
</script>
This is my console output
It shows the full csv(currently), & the users input
changed the csv data into to different arrays if that helps:
array
& Thanks all in advance for taking the time to reply to my silly question!
EXTRA Clarification:
What I'm trying to do is a validate website checker.
So the user inputs their serial through an simple input field. & I have the serials in a csv file with an extra column that has the name matching to the serial.
So if the user inputs 1234567 it is present in the CSV file, my current code returns value = true for that. as it is present in the CSV file.
But I want it to return the value next to 1234567 (so in the second Column) instead, in this case "test1". So I can use that value instead of just a standard "Valid" text to be pushed back onto the website.
You can match values of two arrays by their index. In your case, I think it's easiest to use Array.map() to return a transformed array based on the one you loop trough. So for example, if you have two arrays called namesArray and valuesArray, do the following:
const validationResults = valuesArray.map((value, index) => {
return {
valid: checkValidity(value), // or whatever your validation function is called
name: namesArray[index] // match the index of the namesArray with the index of this one (valuesArray)
};
// or `return namesArray[index] + ', valid: ' + checkValidity(value)`
});
This loops through the valuesArray, and validationResults will then be an array of what you return per each item in the map function above.
One important note is that this assumes the arrays are both in the same order . If you want to sort them, for instance, do this after this.
Looking up and registering the values in a Map seems like the best answer.
// ...
const serialdata = await response.text();
const seriallookup = new Map();
// Set all Serial values to Names
for (let s in serialdata.split("\n")) {
let data = s.split(',');
seriallookup.set(data[0], data[1]);
}
Using this, checking for a serial's existance could be done with .has()
if (inputserialnumber.length == 7 && seriallookup.has(inputserialnumber)) {
And set to the elements text using
document.getElementById('validity').innerHTML = serialdata.get(inputserialnumber);
If the .csv file most likely wouldn't change between multiple requests (or if you only send just one request), you should probably initialize and request the data outside of the function.
Thank you all for the feedback.
I have not been able to use your suggestions exactly as intended.
But I managed to combine the idea's and create a new piece that does the trick for me!
const checkm = document.getElementById('check');
checkm.addEventListener('click', serialChecker)
async function serialChecker(){
const url = 'http://localhost/validator2/naamloos.csv';
const response = await fetch(url);
// wait for the request to be completed
const serialdata = await response.text();
const table = serialdata.split('\r\n');
const serialsArray = [];
const nameArray = [];
table.forEach(row =>{
const column = row.split(',');
const sArray = column[0];
const nArray = column[1];
serialsArray.push(sArray);
nameArray.push(nArray);
})
var array1 = serialsArray,
array2 = nameArray,
result = [],
i, l = Math.min(array1.length, array2.length);
for (i = 0; i < l; i++) {
result.push(array1[i], array2[i]);
}
result.push(...array1.slice(l), ...array2.slice(l));
function testfunction(array, variable){
var varindex = array.indexOf(variable)
return array[varindex+1]
}
//calling the function + userinput for serial
const inputserialnumber = document.getElementById('serialnumber').value.toString();
console.log(testfunction(result, inputserialnumber))
if(serialsArray.includes(inputserialnumber) == true && inputserialnumber.length == 7 ){
document.getElementById('validity').innerHTML = "Valid " + testfunction(result, inputserialnumber);
startConfetti();
}else {
document.getElementById('validity').innerHTML = "Invalid";
stopConfetti();
}
}
Hope this can help someone out in having an input field on their website with a .csv file in the backend (possible to have multiple for the user to select with a dropdown box with the async function).
This will check the file & will return the value from the csv that matches the serial!(based on serial number & length of the serial number(7characters))

Using a forEach inside a filter to organize data

I am trying to filter through a large set of data that has an array nested inside whos values I need to compare against a string. To compare them I need to clean the strings because its coming through user input and spacing/capitalization may vary. So I had my functions working through a filter that looked like this
data initially looked like
formularyOptions = [{Condition: "headache"...}{Condition: "hair loss"..}...]
chiefComplaint = "Headache"
const cleanText = (value) => {
let str = value;
if (!str) {
return value;
}
str = str.toLowerCase();
str = str.replace(/\s/g, "");
return str;
};
let formularyList = formularyOptions.filter(
(item) => !!chiefComplaint && cleanText(item.Condition) === cleanText(chiefComplaint),
);
And this worked just fine but now
My data looks like this:
[{Condition: ["headache", "migraine"]...}{Condition: ["hair loss"]..}...]
Ive tried changing my filter to loop through the Conditions array but that doesnt return anything for some reason I dont understand. And the includes method wont work since it is case sensitive. Any advice on how to approach this or even why a forEach wouldnt work inside a .filter would be super helpful this is my attempt with a for loop:
let formularyList = formularyOptions.filter(
(item) => !!chiefComplaint && item.Condition.forEach((condition) => cleanText(condition) === cleanText(chiefComplaint)),
);
which just returns an empty array..
You are including a .forEach(...) inside a boolean conditional, but it is void, it only loops, nothing is returnted.
I think you actually need to use the .some(...) instead, which will try to find some item that corresponds to the condition:
let formularyList = formularyOptions.filter(
(item) => !!chiefComplaint && item.Condition.some((condition) => cleanText(condition) === cleanText(chiefComplaint)),
);

pure javascript, filter box doesn't filter properly

I have an array of devices, each device has own unique id, I wish to make searchBox which will filter by this id. So far I managed it partly, so it checks if character from input match character from device-id. However not in way I would want that, example below:
id =35678; input.value = 5
it shouldn't work as first character is 3
id = 35679; input.value= 35
it should work as first character is same
Problem is in match/include function, but no really idea how to replace it to make it work
input_box.addEventListener('keyup', function(){
var search_result = this.value;
var device = document.querySelectorAll('[device_id]')
var array_of_devices = [];
for (var i = 0; i < device.length; i++) {
array_of_devices.push(device[i].getAttribute('device_id'))
}
array_of_devices.forEach(el => {
if (!el.match(search_result)) {
var not_matched = document.querySelector(`[device_id="${el}"]`)
not_matched.style.display = "none"
} else {
var matched = document.querySelector(`[device_id="${el}"]`)
matched.style.display = "block"
}
})
})
You can use startsWith instead of match
let arr = ['35678', '451234', '45454', '56565']
let find = (value) =>{
return arr.filter(id=> id.startsWith(value))
}
console.log(find(5))
console.log(find(35))
console.log(find(46))
Instead of using .match you can simply use .indexOf and check the index, if it 0 then the entered string is matching the device name from the begining.
array_of_devices.forEach(el => {
// Condition below is changed to use indexOf
if (el.indexOf(search_result) === 0) {
var not_matched = document.querySelector(`[device_id="${el}"]`)
not_matched.style.display = "none"
} else {
var matched = document.querySelector(`[device_id="${el}"]`)
matched.style.display = "block"
}
});
I would suggest you to build a string of device elements based on the search string and add it to your DOM instead of modifying the display properties. This is costing you a bunch of DOM operations which is computationally heavy.
Notice each id in array should be string
const ids = ['3575', '5555']
const found = value => ids.filter(i => i.indexOf(value, 0) === 0)
console.log(found(5));
console.log(found(35));

localStorage, find the difference within the old and new value

I need to find out the difference in the old and new value of the localStorage when the change event if triggered.
I can toggle the same localStorage key within different tabs, so if I add one the values would be:
'1234,4321'
But then when I remove one it would be:
'1234'
My code below will convert the string to an array, separating the comma. However this only seems to work on way around, so if I remove one the code below will display an empty array, instead of the removed number.
window.addEventListener('storage', function (e) {
if (e.key === 'favourites') {
let newv = e.newValue.split(',').filter(id => !!id);
let oldv = e.oldValue.split(',').filter(id => !!id);
let difference = newv.filter(function (i) {
return oldv.indexOf(i) === -1;
});
console.log(difference);
}
});
What is the best way to do this!?
So you need to check for added by looking to see if the original does not have it from the new values. And to check for a removed item, you need to check that the id does not exist in the orginal values.
const oldValue = '1234,4321'
const newValue = '1234,5555'
const oldValueIds = oldValue.split(",")
const newValueIds = newValue.split(",")
const removed = oldValueIds.filter(id => !newValueIds.includes(id))
const added = newValueIds.filter(id => !oldValueIds.includes(id))
console.log('removed: ', removed)
console.log('added: ', added)

AngularJS - Programmatically check whether filter exists

Is there a way to programmatically check whether a filter with a given name exists?
I developed a directive to process page content based on a string input, I want it to react differently in case a certain part of the string corresponds to a filter that exists in my system. For example I have a localize filter:
// Somewhere in the code
var myInput = 'localize';
// Somewhere else
var contentToProcess = 'my content';
var result = '';
if ($filter.hasOwnProperty(myInput)) // TODO: this is the part I'm trying to figure out
result = $filter(myInput)(contentToProcess);
else
result = 'something else';
Jonathan's answers is also acceptable, but I wanted to find a way to check if a filter exists without using a try catch.
You can see if a filter exists like this:
return $injector.has(filterName + 'Filter');
The 'Filter' suffix is added by angular internally, so you must remember to add it or you will always return false
Solution
This seems to work for me.
var getFilterIfExists = function(filterName){
try {
return $filter(filterName);
} catch (e){
return null;
}
};
Then you can do a simple if check on the return value.
// Somewhere in the code
var myInput = 'localize';
var filter = getFilterIfExists(myInput);
if (filter) { // Check if this is filter name or a filter string
value = filter(value);
}
Bonus
If you are looking to parse apart a filter string for example 'currency:"USD$":0' you can use the following
var value; // the value to run the filter on
// Get the filter params out using a regex
var re = /([^:]*):([^:]*):?([\s\S]+)?/;
var matches;
if ((matches = re.exec(myInput)) !== null) {
// View your result using the matches-variable.
// eg matches[0] etc.
value = $filter(matches[1])(value, matches[2], matches[3]);
}
Pull it all together
Wish there was a more elegant way of doing this with angular however there doesn't seem to be.
// Somewhere in the code
var myInput = 'localize';
var value; // the value to run the filter on
var getFilterIfExists = function(filterName){
try {
return $filter(filterName);
} catch (e){
return null;
}
};
var filter = getFilterIfExists(this.col.cellFilter);
if (filter) { // Check if this is filter name or a filter string
value = filter(value);
} else {
// Get the filter params out using a regex
// Test out this regex here https://regex101.com/r/rC5eR5/2
var re = /([^:]*):([^:]*):?([\s\S]+)?/;
var matches;
if ((matches = re.exec(myInput)) !== null) {
// View your result using the matches-variable.
// eg matches[0] etc.
value = $filter(matches[1])(value, matches[2], matches[3]);
}
}
You can just do this:
var filter = $filter(myInput);
if (filter)
result = filter(contentToProcess);
else
result = 'something else';
Undefined and null values are treated as false in JS, so this should work in your case.

Categories