Execute the else statement if none of the items are found - javascript

I have this for loop, and I would like to execute the else in the for loop only if none of the if conditions are met. The for loop runs until every item in the database has been checked. If none of the items in the database matches the user input then I want to run the else.
Right now, it runs the else right after the first try which means if the item matches is in the last row, it will just throw it in the error page since it stops the evaluation at the first iteration.
for(var i=0; i< rows.length; i++) {
if (rows[i].hashtag == userEnteredHashtag) {
// Display the choose Box page
res.render('chooseBox', {});
}
else {
// Display the invalid hashtag page
res.render('invalidHashtag', {});
}
}

Just move the else portion outside of the loop and execute it based on a flag
var wasFound = false;
for (var i = 0; i < rows.length; i++) {
if (rows[i].hashtag == userEnteredHashtag) {
// ...
wasFound = true; // set the flag here
}
}
if (!wasFound) {
res.render('invalidHashtag', {});
}

So add a check outside.
var hasMatch = false;
for (var i = 0; i < rows.length; i++) {
if (rows[i].hashtag == userEnteredHashtag) {
// Display the choose Box page
res.render('chooseBox', {});
hasMatch = true;
}
}
if (!hasMatch) {
// Display the invalid hashtag page
res.render('invalidHashtag', {});
}

Create a variable to track whether your condition has been met:
var isValid = true;
for(var i=0; i< rows.length; i++) {
if (rows[i].hashtag != userEnteredHashtag) {
isValid = false
}
}
isValid ? res.render('chooseBox') : res.render('invalidHashtag')

Another way to do it is to use filter and forEach.
var rows = [{hashtag: '#a'}, {hashtag: 'b'}, {hashtag: 'c'}];
var userEnteredHashTag = '#a';
var matchingRows = rows.filter(row => row.hashtag === userEnteredHashTag);
if (matchingRows.length) {
matchingRows.forEach(row => console.log(row));
} else {
console.log('invalid');
}

Related

JS object changed to true, still treated like false

When setting value of object to true it looks and seems it changed it but I still cant use it(as it stayed false).
validateNextMove() {
Card.setArrayNextMoveValid(this.cardRepository.findAll(), false);
let client = this.clientRepository.findByTurn(true);
let provjera = 0;
if (client instanceof UNOClient) {
let cards = client.getCards();
for (let i = 0; i < cards.length; i++) {
if (this.cardCanBePlaced(cards[i])) {
provjera++;
cards[i].setNextMoveValid(true);
console.log(cards[i].getNextMoveValid());
console.log(provjera);
}
}
if (provjera == 0) {
for (let i = 0; i < cards.length; i++) {
cards[i].setNextMoveValid(true);
console.log(cards[i].getNextMoveValid());
console.log(provjera);
}
}
How do I fix this ?
this is my method for checking if card can be place:
cardCanBePlaced(card){
let current = this.discardDeck.slice(-1)[0];
if(typeof current === 'undefined'){
return true;
}
//Check if card is allowed
if(
card.getColor() === current.getColor()
){
return true;
}
return false;
}
if in above mtehod i add global variable to count if there is any available it still doesnt make it work, something like this(counter++ if there is available card of that color)
if(card.getColor()!= current.getColor() && counter==0){
return true;
}

How to exit a loop inside a functionin Javascript

I am trying to exit a function call when a value is found, and I can not wrap my head around this.
Using the debugger I've noticed that the return found; line makes execution jump to the end of the function, OK... but after that another iteration on the for loop is started.
I've tried using break too.
My code is below.
Edited
I've checked the logic on the debugger, adding a breakpoint on found = true and it works fine, so the only thing left is that it should exit properly after that...
// Tree traversal until answer found via answer.id
function locateAnswer(wholeTree, answerID) {
var found = false;
if (wholeTree.answers) { // checks if next_queston is populated first
for (var i = 0; i < wholeTree.answers.length; ++i) {
if (wholeTree.answers[i].id == answerID) {
console.log("found!");
found = true;
return found; // TRIED break; TOO
} else {
for (var j = 0; j < $scope.breadcrumbs.length; ++j) {
if ($scope.breadcrumbs[j].question == wholeTree.question) {
// if already exist, we pop elements until it does not exist anymore
while ($scope.breadcrumbs[j]) {
$scope.breadcrumbs.pop();
}
}
}
// we push the new breadcrumb
$scope.breadcrumbs.push({ "question": wholeTree.question, "answer": wholeTree.answers[i].answer });
locateAnswer(wholeTree.answers[i].next_question, answerID);
}
}
}
// ALSO TRIED return HERE AFTER break
};
You should use break inside the loop and return statement at the end of the function. Please updated code
function locateAnswer(wholeTree, answerID) {
var found = false;
if (wholeTree.answers) { // checks if next_queston is populated first
for (var i = 0; i < wholeTree.answers.length; ++i) {
if (wholeTree.answers[i].id == answerID) {
console.log("found!");
var found = true;
break; // TRIED break; TOO
} else {
for (var j = 0; j < $scope.breadcrumbs.length; ++j) {
if ($scope.breadcrumbs[j].question == wholeTree.question) {
// if already exist, we pop elements until it does not exist anymore
while ($scope.breadcrumbs[j]) {
$scope.breadcrumbs.pop();
}
}
}
// we push the new breadcrumb
$scope.breadcrumbs.push({ "question": wholeTree.question, "answer": wholeTree.answers[i].answer });
locateAnswer(wholeTree.answers[i].next_question, answerID);
}
}
}
// ALSO TRIED return HERE AFTER break
return found;
};
Try to use break instead of return inside the for loop

JQuery and Bootstrap based toaster

In my HTML page i have table in which each row, there is a check box.
My requirement is if more then one row is selected i.e. if the array length is 2, a toaster message has to be shown.
I got a use case there and it is,
if i select 2 rows(array length is 2), message is showing .
Then select 3rd row(array length is 3) and again deselect 3rd row(array length is 2 again).
Now also it shows the message. Here i don't want that toast.
My approach is :
$scope.toggleOne = function () {
if ($scope.selectedUsers.length === 2) {
showMessage();
}
for (var j = 0; j < $scope.users.length; j++) {
if (!$filter('filter')($scope.selectedUsers, $scope.users[j].id, true).length) {
$scope.selectAllCheckboxOfUsers = false;
return;
}
}
$scope.selectAllCheckboxOfUsers = true;
}
If you want to display the message just when going from 1 selected to 2 selected, you can check for that:
var previousSelectedNum = 0;
$scope.toggleOne = function () {
if ($scope.selectedUsers.length === 2 && previousSelectedNum === 1) {
showMessage();
}
// ...
previousSelectedNum = $scope.selectedUsers.length;
}
You can use a flag such as,
var isMessageShown = false;
Then in your function use as,
$scope.toggleOne = function () {
if($scope.selectedUsers.length === 1){
isMessageShown = false;
}
if ($scope.selectedUsers.length === 2 && !isMessageShown) {
isMessageShown = true;
showMessage();
}
for (var j = 0; j < $scope.users.length; j++) {
if (!$filter('filter')($scope.selectedUsers, $scope.users[j].id, true).length) {
$scope.selectAllCheckboxOfUsers = false;
return;
}
}
$scope.selectAllCheckboxOfUsers = true;
}

Multiple Email Validation using regex. Loop terminates after first validation

I think I am very close here.
I'm trying to iterate through an array and at each iteration, check whether the value is a valid email address.
The problem is, the loop terminates once it hits either a false or a true. How do I iterate through an array without terminating the loop?
validateForm: function() {
var emails = $('#email-addresses').val(),
emailArray = emails.split(',');
for (var i = 0; i < emailArray.length; i++) {
if( ! this.validateEmail(emailArray[i].trim())) {
return false;
}
return true;
};
},
validateEmail: function(email) {
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
It depends on what you want to do here. If you want to hold a result for every check then look at lincb answer. If you want just a true / false about whether all emails were valid then do:
validateForm: function() {
var emails = $('#email-addresses').val(),
emailArray = emails.split(',');
var isValid = true;
for (var i = 0; i < emailArray.length && isValid == true; i++) {
if( ! this.validateEmail(emailArray[i].trim())) {
isValid = false;
}
};
return isValid;
},
In Javascript, return will end the function regardless of any loops. Here is a possible fix:
validateForm: function() {
var emails = $('#email-addresses').val(),
emailArray = emails.split(',');
var returns = new Array();
for (var i = 0; i < emailArray.length; i++) {
if( ! this.validateEmail(emailArray[i].trim())) {
returns[i] = false;
}
returns[i] = true;
}
return returns;
},

How to validate just one checkbox?

I'm working on a piece of code from an open source library called gvalidator. The following checkbox validate function only works when I have two or more checkboxes. For some reason the if(elements[i]checked) line is not returning true when elements only has 1 object in the array.
Anyone have a guess as to why this is happening? Thanks!
this.validate = function() {
// Check if the form has a value set for this checkbox
// by cycling through all of the checkboxes
var elements = document.forms[0].elements[this.field.name];
if(undefined == elements.length){
x = elements;
elements = new Array(x);
}
for (i = 0; i < elements.length; i++) {
if (elements[i].checked) {
document.write(elements[i].name);
this.setState(ONEGEEK.forms.FIELD_STATUS_OK);
return true;
} else {
if (this.modified !== true || !this.isRequired) {
this.setState(ONEGEEK.forms.FIELD_STATUS_INFO);
} else {
this.setState(ONEGEEK.forms.FIELD_STATUS_EMPTY);
}
}
}
return false;
};
Jan was right... almost. The following is required in the function validate as the the form.elements function won't always return an array - it returns an element in the case there is only 1 match:
// Check if the form has a value set for this checkbox
// by cycling through all of the checkboxes
var elements = document.forms[0].elements[this.field.name];
if (elements.length === undefined) {
elements = [ elements ];
}
It is also required in the setup function before it adds the validation events in the first place:
this.setup = function() {
...
// Add events to ALL of the items
var elements = document.forms[0].elements[this.field.name];
if (elements.length === undefined) {
elements = [ elements ];
}
for (i = 0; i < elements.length; i++) {
_du.addEvent(elements[i], 'click', this.applyFieldValidation(this));
_du.addEvent(elements[i], 'click', this.applyContextInformation(this));
_du.addEvent(elements[i], 'change', this.applyFieldModification(this));
}
}
I have updated the source code at code http://code.google.com/p/gvalidator/, the latest binary is available for download here: http://code.google.com/p/gvalidator/downloads/list.
There are some serious and some minor flaws in your code. This is how it should look like. Test this code and tell me if it still does not work and provide any error messages in the error console.
this.validate = function () {
// Check if the form has a value set for this checkbox
// by cycling through all of the checkboxes
var elements = document.forms[0].elements[this.field.name];
if (elements.length === undefined) {
elements = [ elements ];
}
for (var i = 0, ii = elements.length; i < ii; ++i) {
if (elements[i].checked) {
document.write(elements[i].name);
this.setState(ONEGEEK.forms.FIELD_STATUS_OK);
return true;
} else {
if (this.modified !== true || !this.isRequired) {
this.setState(ONEGEEK.forms.FIELD_STATUS_INFO);
} else {
this.setState(ONEGEEK.forms.FIELD_STATUS_EMPTY);
}
}
}
return false;
};

Categories

Resources