Can't break out of some() array method - javascript

I got a click event attached to a button to perform a search that checks if a certain element matches a certain condition. In the snippet below there is a some() array method that checks the 'entriesFound' array for the element that matches a certain condition. However everything works find till the else if(el.name !== name.value) condition. The alertbox shows but I need to click the OK button in the alertbox as many times as there are elements in the entriesFound array.
import { persons } from './main.js';
export let entriesFound = []
export const searchBtn = document.querySelector('.search').addEventListener('click' , function() {
let name = document.querySelector('.searchInput')
if(name.value === "") {
alert('No search query!')
return;
}
entriesFound.some( el => {
if(el.name === name.value){
name.value = ""
alert("You\'ve already found what you are looking for!")
el.remove();
// from here things go wrong
}else if(el.name !== name.value){
alert("No data found!")
return;
}
})
persons.some( el => {
if(el.name === name.value) {
addItem(el)
entriesFound.push(el);
}
})
name.value = ""
localStorage.setItem('entriesFound', JSON.stringify(entriesFound))
})

You should use the return value of some and you can utilize find:
import { persons } from "./main.js";
export let entriesFound = [];
export const searchBtn = document
.querySelector(".search")
.addEventListener("click", function () {
let name = document.querySelector(".searchInput");
if (name.value === "") {
alert("No search query!");
return;
}
const entryExists = entriesFound.some((el) => el.name === name.value);
if (entryExists) {
name.value = "";
alert("You've already found what you are looking for!");
el.remove();
// from here things go wrong
} else {
alert("No data found!");
return;
}
const item = persons.find(el.name === name.value);
if (item !== null) {
addItem(item);
entriesFound.push(item);
}
name.value = "";
localStorage.setItem("entriesFound", JSON.stringify(entriesFound));
});

Thanks all of you. I combined your solutions. I used regular for loops and the every() array method.
import { persons } from "./main.js";
export let entriesFound = [];
export const searchBtn =
document.querySelector('.search').addEventListener('click' , () => {
let name = document.querySelector('.searchInput')
if(name.value === "") {
alert('No search query!')
return;
}
if(entriesFound.length > 0){
for(let el of entriesFound){
if(el.name === name.value) {
alert('You have found that one already!')
name.value = ""
return;
}
}
}
if(persons.length > 0 ){
for(let el of persons) {
if(el.name === name.value) {
addItem(el)
entriesFound.push(el)
}
}
}else if(persons.length === 0 ){
alert('No data!')
name.value = ""
return;
}
let noMatch = persons.every( el => el.name !== name.value)
console.log(noMatch)
if(noMatch === true){
alert('No match!');
name.value = ""
return;
}
name.value = ""
localStorage.setItem('entriesFound', JSON.stringify(entriesFound))
});

Related

Why does this my recursive function work after dividing a tag.class selector without dividing the matching tag.class new one?

I've been trying to do some html and css but I'm really bad at this so far. I was using a function that would check if two selectors match. A friend of mine came up with this code but neither of us fully understands how the return of the "tag.class" case works. My question is, if it doesn't divide the newSelector, how can it succesfully check the tag and class?
var matchFunctionMaker = function(selector) {
var selectorType = selectorTypeMatcher(selector);
var matchFunction;
if (selectorType === "id") {
matchFunction = nuevoSelector => '#' + nuevoSelector.id === selector;
} else if (selectorType === "class") {
matchFunction = nuevoSelector => {
var lista = nuevoSelector.classList;
for (let x of lista) {
if (selector === '.' + x) return true;
}
return false;
}
} else if (selectorType === "tag.class") {
matchFunction = nuevoSelector => {
var [tag, clase] = selector.split('.');
return matchFunctionMaker(tag) (nuevoSelector) && matchFunctionMaker(`.${clase}`) (nuevoSelector);
};
} else if (selectorType === "tag") {
matchFunction = nuevoSelector => nuevoSelector.tagName.toLowerCase() === selector.toLowerCase();
}
return matchFunction;
};
Thanks in advance!

How to check all input has value and do something

i have these inputs and i wanted to check every one of them has value then do something;
const tch_family_name = document.getElementById('tch_family_name');
const tch_lastname = document.getElementById('tch_lastname');
const tch_name = document.getElementById('tch_name');
const tch_phone = document.getElementById('tch_phone');
const first_alph = document.getElementById('first_alph');
const second_alph = document.getElementById('second_alph');
const third_alph = document.getElementById('third_alph');
const tch_bday = document.getElementById('tch_bday');
const textarea1 = document.getElementById('textarea1');
and I'm checking they have value or not like this
function checkEmpty(check) {
for (i = 0; i < check.length; i++) {
if (check[i].value == "" || check[i].value == " " || check[i].value == null) {
check[i].classList.add('inputErrorBorder')
} else {
check[i].classList.remove('inputErrorBorder')
}
}
}
//mainInfo button id
mainInfo.addEventListener('click', () => {
test = [tch_family_name, tch_lastname, tch_name, tch_phone, first_alph, second_alph, third_alph, tch_bday, textarea1]
checkEmpty(test)
})
now how to do something when all input have value;
I tried else if() but it gave an incorrect result for example when first input don't value then it wont add inputErrorBorder class to a second or third inputs.
Please help;
One of the easiest ways to add this to your current setup is to add a flag variable to the checkEmpty function and return that value. Then process the results in the EventListener
checkEmpty With hasEmpty Flag
function checkEmpty(check) {
let hasEmpty = false;
for (let i = 0; i < check.length; i++) {
if (check[i].value === "" || check[i].value === " " || check[i].value == null) {
check[i].classList.add('inputErrorBorder');
hasEmpty = true;
} else {
check[i].classList.remove('inputErrorBorder');
}
}
return hasEmpty;
}
Using hasEmpty flag from checkEmpty
mainInfo.addEventListener('click', () => {
let test = [tch_family_name, tch_lastname, tch_name, tch_phone,
first_alph, second_alph, third_alph, tch_bday, textarea1];
let hasEmpty = checkEmpty(test);
if (!hasEmpty) {
// All Have Value
} else {
// Something has missing value
}
})

console.log and arithmatic operations does not work inside (addEventListener) javascript

i try to create typing test web application //error ///
this code i copied from github https://github.com/WebDevSimplified/JS-Speed-Typing-Game
i try to add timer when user press a key..
var err=0;
let sttime =0;
console.log(sttime);
quoteInputElement.addEventListener('input', () => {
err ++; /////does not work
console.log(sttime); ///does not work
console.log('jbjabj');
const arrayQuote = quoteDisplayElement.querySelectorAll('span');
const arrayValue = quoteInputElement.value.split('');
let correct = true;
arrayQuote.forEach((characterSpan, index) => {
const character = arrayValue[index];
if (character == null) {
characterSpan.classList.remove('correct');
characterSpan.classList.remove('incorrect');
correct = false
} else if (character === characterSpan.innerText) {
characterSpan.classList.add('correct');
characterSpan.classList.remove('incorrect');
} else {
characterSpan.classList.remove('correct');
characterSpan.classList.add('incorrect');
correct = false;
}
})
})
console.log(sttime);
if(sttime == 1){
startTimer();
}

Merging two functions into one to simplify the code

I got these two functions, and they work great.
But since I only call global.replaceFields from global.translateAll then I want to get rid of global.replaceFields and put its functionality inside global.translateAll
How would you go about merging global.replaceFields into global.translateAll without losing the current functionality?
Thanks :)
// Translate everything in that field
global.translateAll = (textfield, usersLanguage) => {
for (var property in textfield) {
if (!textfield.hasOwnProperty(property)) {
return false;
} else if (typeof textfield[property] !== "object") {
textfield[property] = global.replaceFields(textfield[property], usersLanguage);
} else {
global.translateAll(textfield[property], usersLanguage);
}
}
}
// Translate everything in that field
global.replaceFields = (textfield, usersLanguage) => {
// Keep running until all fields are replaced
while (textfield.indexOf("{{") != -1) {
// isolate the field
let fromField = textfield.substring((textfield.indexOf("{{") + 2), (textfield.indexOf("}}")));
let toField = ""
// If its a translated text
if (fromField.indexOf("trans") != -1) {
toField = usersLanguage[fromField];
textfield = textfield.replace("{{" + fromField + "}}", toField);
}
}
return (textfield);
}
This should work
global.translateAll = (textfield, usersLanguage) => {
var replaceFields = (textfield, usersLanguage) => {
// Keep running until all fields are replaced
while (textfield.indexOf("{{") != -1) {
// isolate the field
let fromField = textfield.substring((textfield.indexOf("{{") + 2), (textfield.indexOf("}}")));
let toField = ""
// If its a translated text
if (fromField.indexOf("trans") != -1) {
toField = usersLanguage[fromField];
textfield = textfield.replace("{{" + fromField + "}}", toField);
}
}
return (textfield);
}
for (var property in textfield) {
if (!textfield.hasOwnProperty(property)) {
return false;
} else if (typeof textfield[property] !== "object") {
textfield[property] = replaceFields(textfield[property], usersLanguage);
} else {
global.translateAll(textfield[property], usersLanguage);
}
}
}

DeDuplicating array of Objects javascript

Working on a project that is taking in 5 similar SQL databases, and I need to detect and filter out duplicates. I think I'm on the right track, but I'm not quite there yet. I am attempting to follow these steps to accomplish this:
start a .forEach() for the main array passing in an item object.
create a filtered array via let filtered = Array.filter(x => x.id !== item.id); to keep from checking against itself.
start a .forEach() for the filtered array passing in comparison as the parameter.
initialize variables for similarity in Name, Phone, and Email fields.(i.e.nameSimilarity, phoneSimilarity, and emailSimilarity)
If item.email and comparison.email aren't empty, compare the strings and store the similarity percentage in emailSimilarity else emailSimilarity=0.
If item.phone and comparison.phone aren't empty, compare the strings and store the similarity percentage in phoneSimilarity else phoneSimilarity=0.
Combine item.firstName and item.lastName into an variable called itemFullName and combine comparison.firstName and comparison.lastName into a variable called comparisonFullName.
If itemFullName and comparisonFullName aren't empty, compare the strings and store the similarity percentage in nameSimilarity else nameSimilarity=0.
if any of the percentages in emailSimilarity, nameSimilarity, or phoneSimilarity, add item plus the similarity variables and comparison.id to the duplicates array, and splice it out of the original array.
This is the code that I've written to follow these steps, but it appears that I'm getting duplicate entries in the duplicates array. I'm not sure why it's not working as expected, but I have a hunch that I can't really expect the original array to mutate inside the forEach() operation.
fullArray.forEach(item => {
let filtered = fullArray.filter(x => x.externalId !== item.externalId);
filtered.forEach(comparison => {
let emailSimilarity, phoneSimilarity, nameSimilarity;
if ((item.email !== '') && (comparison.email !== '')) {
emailSimilarity = strcmp.jaro(item.email, comparison.email);
} else {
emailSimilarity = 0;
}
if ((item.phone !== '') && (comparison.phone !== '')) {
phoneSimilarity = strcmp.jaro(item.phone, comparison.phone);
} else {
phoneSimilarity = 0;
}
let itemFullName = `${item.firstName} ${item.LastName}`.trim() || '';
let comparisonFullName = `${comparison.firstName} ${comparison.LastName}`.trim();
if (((itemFullName !== '') && (comparisonFullName !== '')) || ((itemFullName.indexOf('Group')! > 0) && (comparisonFullName.indexOf('Group') !>0))) {
nameSimilarity = strcmp.jaro(itemFullName, comparisonFullName);
} else {
nameSimilarity = 0;
}
if ((emailSimilarity || phoneSimilarity || nameSimilarity) > 0.89) {
let dupesOutput = Object.assign({}, item, { similarName: nameSimilarity, similarEmail: emailSimilarity, similarPhone: phoneSimilarity, similarTo: comparison.externalId });
dupes.push(dupesOutput);
fullArray = fullArray.filter(x => x.externalId !== item.externalId);
}
});
});
Where's the issue?
Assuming the similarity check is working, the problem is that you're reassigning a new array to fullArray while still being in the forEach loop of the old one.
I'd suggest you use Array.filter:
var filteredArray = fullArray.filter(item => {
return !fullArray.some(comparison => {
if(comparison.externalId==item.externalId)
return false;
let emailSimilarity, phoneSimilarity, nameSimilarity;
if ((item.email !== '') && (comparison.email !== '')) {
emailSimilarity = strcmp.jaro(item.email, comparison.email);
} else {
emailSimilarity = 0;
}
if ((item.phone !== '') && (comparison.phone !== '')) {
phoneSimilarity = strcmp.jaro(item.phone, comparison.phone);
} else {
phoneSimilarity = 0;
}
let itemFullName = `${item.firstName} ${item.LastName}`.trim() || '';
let comparisonFullName = `${comparison.firstName} ${comparison.LastName}`.trim();
if (((itemFullName !== '') && (comparisonFullName !== '')) || ((itemFullName.indexOf('Group')! > 0) && (comparisonFullName.indexOf('Group') !>0))) {
nameSimilarity = strcmp.jaro(itemFullName, comparisonFullName);
} else {
nameSimilarity = 0;
}
if ((emailSimilarity || phoneSimilarity || nameSimilarity) > 0.89) {
let dupesOutput = Object.assign({}, item, { similarName: nameSimilarity, similarEmail: emailSimilarity, similarPhone: phoneSimilarity, similarTo: comparison.externalId });
dupes.push(dupesOutput);
return true;
}else
return false;
});
});

Categories