Detailed age check for users - javascript

/* I want to check for the age of the user, if 18 or above, grant access. If not proceed to the next block where they are asked if they are given permission by their parents. If (yes || Yes || YES) grant access. If (no || No || NO) deny access. If anything apart from the (yes(s) and no(s)) return (Wrong input!). If (!yes(s) and !no(s) "ie, the user cancels,") return (Try Next time!) */
let age = prompt('How old are you?', [18]);
function ageChecker(age) {
if (age >= 18) {
return 'Access Granted!';
}
else if (!age) {
return 'Sorry Enter Your Age!';
}
else {
let confirmation = prompt('Do you have permission from your parents?', ['Yes']);
let posResult1 = 'yes';
let posResult2 = 'Yes';
let posResult3 = 'YES';
let negResult1 = 'no';
let negResult2 = 'No';
let negResult3 = 'NO';
if (confirmation) {
if (posResult1 || posResult2 || posResult3) {
return 'Access Granted!';
}
else if (negResult1 || negResult2 || negResult3) {
return 'Access Denied!';
}
}
else {
return 'Wrong Input Sucker!';
}
return confirmation;
}
}
alert( ageChecker(age) );

The confirmation variable's output should not be compared with the multiple variables, instead of just use the toLowerCase() function
let age = prompt('How old are you?', [18]);
function ageChecker(age) {
if (age >= 18) {
return 'Access Granted!';
}
else if (!age) {
return 'Sorry Enter Your Age!';
}
else {
let confirmation = prompt('Do you have permission from your parents?', ['Yes']);
if ('yes' == confirmation.toLowerCase()) {
return 'Access Granted!';
}else if('no' == confirmation.toLowerCase()){
return 'Access Denied!';
}else if(!confirmation){
return 'Try next time';
}
else {
return 'Wrong Input Sucker!';
}
return confirmation;
}
}
alert( ageChecker(age) );

A couple of things to note:
The result you get back from a prompt is of type string, so if you use age >= 18 it won't be doing a proper comparison. Therefore if you're expecting the user to enter a number, you should convert the result using parseInt().
The answer to a prompt is stored in the variable you assign the prompt function to, so if you do const foo = prompt("What is your name");, the answer will be stored in variable foo. Therefore, your if statements need to check the confirmation variable.
If you are not reassigning a variable, make it a habit to use constants (i.e. const foo = ... instead of let foo = ...).
Lastly, you can use toLowerCase() so you only have to compare the confirmation answers to "yes" and/or "no".
This is a way in which you could write the function instead:
const age = parseInt( prompt('How old are you?', [18]), 10 );
function ageChecker(age) {
if (!age) {
return 'Sorry Enter Your Age!';
}
if (age >= 18) {
return 'Access Granted!';
}
else {
const confirmation = prompt('Do you have permission from your parents?', ['Yes']);
if (!confirmation) {
return 'Wrong Input Sucker!';
}
if (confirmation.toLowerCase() === 'yes') {
return 'Access Granted!';
}
else if (confirmation.toLowerCase() === 'no') {
return 'Access Denied!';
}
return 'Wrong Input Sucker!';
}
}
alert( ageChecker(age) );
Another neat thing you can do when checking the confirmation is using a switch statement instead of an if statement:
const age = parseInt( prompt('How old are you?', [18]), 10 );
function ageChecker(age) {
if (!age) {
return 'Sorry Enter Your Age!';
}
if (age >= 18) {
return 'Access Granted!';
}
else {
const confirmation = prompt('Do you have permission from your parents?', ['Yes']);
if (!confirmation) {
return 'Wrong Input Sucker!';
}
switch (confirmation.toLowerCase()) {
case 'yes':
return 'Access Granted!';
case 'no':
return 'Access Denied!';
default:
return 'Wrong Input Sucker!';
}
}
}
alert( ageChecker(age) );
Depending on the use, switch statements can be a much neater way of checking variables than using a bunch of if statements.

I will expand on Yannik's answer with some advice for what I think is best practice in javascript code.
Use variables to describe conditions in if statements. It's easier to read for other developers, especially if there are several conditions, like hasValidAge, locatedInEurope, and isAdmin.
If the method returns something, return it at the end of the method. That not only makes the code more clear of what it will do, but you are also given a chance to explain - through the variable name - what is returned.
Refactor code. Right now, you have ageChecker with a long if statement, which makes it hard to read. But not only that, you also have a method that makes two things. It's not only checks age, it also asks for the parent's permission. A method should, in best scenario, only do one thing.
I marked the code below to highlight my points.
[EDIT] clarifications based on questions in the comment:
a) The prompt could return undefined if the user removes all text. That will make the code crash later on with confirmation.toLowerCase().
const confirmation = prompt('Do you have permission from your parents?', ['Yes']) // can return undefined
b) I didn't want to sway away too much from your code in my refactor example. If I would have done the refactor properly, I would have used three methods:
function ageCheckerAlert() {
let messageStr = promptAge();
const invalidAge = messageStr == 'Invalid Age';
if (invalidAge) {
messageStr = promptParentsPermission();
}
alert(messageStr);
}
function promptAge() {
let messageStr = 'Invalid Age';
const age = parseInt( prompt('How old are you?', [18]), 10 );
// if statements that changes messageStr, if either valid age or empty input.
return messageStr;
}
function promptParentsPermission() {
// same code as in parentsPermissionChecker() in the snippet below
}
By separating the functionality, you get the added benefit of being able to call promptAge() or promptParentsPermission() alone if you ever would need to do that.
const age = parseInt( prompt('How old are you?', [18]), 10 );
function ageChecker(age) {
let messageStr;
const hasValidAge = age >= 18; // 1
if (!age) {
messageStr = 'Sorry Enter Your Age!';
}
else if (hasValidAge) { // 1
messageStr = 'Access Granted!';
}
else {
messageStr = parentsPermissionChecker(); // 3
}
return messageStr; // 2
}
function parentsPermissionChecker() { // 3
const confirmation = prompt('Do you have permission from your parents?', ['Yes']) || ''; // added a default string.
let messageStr = 'Wrong Input Sucker!';
const typedYes = confirmation.toLowerCase() === 'yes';
const typedNo = confirmation.toLowerCase() === 'no';
if (typedYes) {
messageStr = 'Access Granted!';
}
else if (typedNo) {
messageStr = 'Access Denied!';
}
return messageStr; // 2
}
alert( ageChecker(age) );

Related

I have a problem with JS's if-else statements with several conditions

I am learning if-else statements with several conditions and this easy task is somehow bothering me since the else if in the external condition is being underlined in visual studio code. I cannot seem to fix it. It says 'Declaration or statement expected'. Can you guys please take a look and help me? This is my code.
function solve(input) {
let gender = (input.shift());
let age = Number(input.shift());
if (gender === 'Female') {
if (age >= 18) {
console.log('You are permitted on the website, lady.')
}
} else {
console.log('You are not permitted on the website, lady.')
}
} else if (gender === 'Male') {
if (age >= 18) {
console.log('You are permitted on the website, dude.')
} else {
console.log('You are not permitted on the website, dude.')
}
} else {
console.log('Error')
}
solve(['Female', '13'])
This logic can be vastly simplified - given that you are using the same text - with only the variables of gender and age - these can be made into variables that are then inserted into the phrase that is consoled.
Just beause there are two arguments passed to the function does NOT mean that each variable needs to be within the if / else blocks
function solve(input) {
var gender, ability;
input[0] == 'Female'
? gender = 'lady'
: gender = 'dude';
parseInt(input[1]) >= 18
? ability = 'are'
: ability = 'are not';
console.log('You ' + ability + ' permitted on the website, ' + gender + '.')
}
solve(['Female', '13']); // gives You are not permitted on the website, lady.
solve(['Male', '19']); // give You are permitted on the website, dude.
As already mentioned in the comment section, your else if statement is refering to a function block, but you have to refer to your first if statement. Realign your code/ curly brackets and your code should work as expected:
function solve(input) {
let gender = (input.shift());
let age = Number(input.shift());
if (gender === 'Female') {
if (age >= 18) {
console.log('You are permitted on the website, lady.');
} else {
console.log('You are not permitted on the website, lady.');
}
} else if (gender === 'Male') {
if (age >= 18) {
console.log('You are permitted on the website, dude.');
} else {
console.log('You are not permitted on the website, dude.');
}
} else {
console.log('Error');
}
}
solve(['Female', '13']);
Just a recommendation, close your console log statements with a semicolon (e.g. console.log("output");). Have a look at this post, for more information about closing a statement with a semicolon.

Why is this javascript validation always failing

I've got a classic input validation for an email and a password, but for some reason my logic doesn't work and I can't figure out the part where it fails. This is code I've refactored from some one else and it bugging me quite a lot now
function Validation() {
this.regex = {
email: new RegExp(/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9]+\.[a-zA-Z0-9-]+/),
password: new RegExp(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]{6,13}/),
},
this.email = function () {
let valElement = document.getElementById("mail");
console.log(valElement);
let valueR = valElement.value.toString();
console.log(valueR);
let erorrEl = document.getElementById("error");
let validate_mail = valueR.length == 0 && this.regex.email.test(valueR);
console.log(validate_mail);
console.log(this.regex.email);
if(!validate_mail){
valElement.className = "invalid";
erorrEl.innerHTML = "Please enter a correct email";
erorrEl.className = "error active"
console.log("not validated email");
event.preventDefault();
}else{
valElement.className = "valid";
erorrEl.innerHTML = "";
erorrEl.className = "error"
console.log("validated email");
}
}
this.password = function () {
let valElement = document.getElementById("pass");
let valueR = valElement.value;
let erorrEl = document.getElementById("error2");
let validate_pass = valueR.length == 0 && this.regex.password.test(valueR);
if(!validate_pass){
valElement.className = "invalid";
erorrEl.innerHTML = "Please enter a correct password";
erorrEl.className = "error active"
console.log("not validated password");
event.preventDefault();
}else{
valElement.className = "valid";
erorrEl.innerHTML = "";
erorrEl.className = "error"
console.log("validated password");
}
}
this.form = function(){
if(this.password && this.email){
}else{
}
}
}
var Valdator = new Validation();
Valdator.email();
Valdator.password();
Usually I'm calling these Valdator email and password functions in another file where it's a request from an API, but the idea is the same here, I don't think that woould make a difference
Your RegEx is never being executed because valueR.length == 0 will evaluate to false, which short-circuits your && before it can execute the second part. Remember that if you are AND-ing two statements and the first statements evaluates to false, there is no need to evaluate the second statement because both false && true and false && false evaluate to false.
That being said, it makes no sense to check for valueR.length == 0 as a pre-condition for evaluating a RegEx on valueR - why would we run an RegEx on a 0-length string? You should flip this logic to !==.
And please always use === or !== in the future, as == gets messy with type conversion.
let validate_pass = valueR.length !== 0 && this.regex.password.test(valueR);

prompt validation if null not working inside funcion/while/try javascript

as said on title, validating the prompt if is null (inpname variable) inside the func/while/try wont work. output = {}
meanwhile the testing i did outside works fine.
check the code below please. what did i do wrong?
//works
let test = prompt("testing","aasdasd");
if (test === null) {
console.log("cancel");
}
else {
console.log("ok");
}
let inpname;
//do not work
let func = () => {
while (true) {
try {
inpname = prompt("name ", "name here");
if (inpname.length > 10 || inpname.length <= 3) {
throw "Your name must be at least 10 characters long, but not less than 4";
}
else if ( inpname != inpname.match(/^[a-zA-Z]+$/)) {
throw "A-Z characters accepted only!";
}
//problem here!
else if (inpname === null) {
throw "cant cancel";
}
else {
console.log("success");
break
}
}
catch (err) {
console.log(err);
break
}
}
}
func();
The console outputting {} instead of the exception seems to be a bug in Stack-snippets. You would get more correct output using console.error.
That being said, the issue you're seeing is in part caused because you're not checking that impname is null before you attempt to dereference it.
Changing the ordering of your error checking would solve the problem (Although stack-snippets is still not going to report exceptions as they happen, which is not the behavior you get in a browser)
let func = () => {
while(true) {
var inpname = prompt("name ", "name here");
try {
if (inpname === null) {
throw "cant cancel";
}
if (inpname.length > 10 || inpname.length <= 3) {
throw "Your name must be at least 10 characters long, but not less than 4";
}
if (inpname != inpname.match(/^[a-zA-Z]+$/)) {
throw "A-Z characters accepted only!";
}
return inpname;
} catch(err) {
console.error(err);
}
}
}
func();
Note that you might want to avoid disallowing use of the "cancel" button. If the user doesn't want to provide the requested info, simply exit the app with an appropriate message

jQuery - Checking if array is empty or has attributes

I'm getting an array of Strings, and if the array has items I want to do one thing and if not I want to do the other. I'm not sure how to check if the array is empty of not. Also when stepping through my code in chrome debugger even if the array has items in it the length is still 0 so I can't use formErrors.length > 0.
Here's my code for getting the errors. This works fine and returns an array of error strings or an empty array:
var formErrors = validateFormData(formData);
function validateFormData(data) {
var errors = [];
if (data["title"].length == 0) {
errors["title"] = "Project title required";
}
if (data["client"].length == 0) {
errors["client"] = "Client name required";
}
if (data["date"].length == 0) {
errors["date"] = "Date required";
} else if (!isValidDateFormat(data["date"])) {
errors["date"] = "Date format invalid - Format: dd/mm/yyyy";
}
if (data["status"] == "") {
errors["status"] = "Please select current status for this project";
}
if (data["type"] == "") {
errors["type"] = "Please select a project type";
}
if (data["extras"].length == 0) {
errors["extras"] = "You must select at least one extra for this project";
}
return errors;
}
Then I want to do one thing if there's no errors and another if there is. But this is the bit that won't work for me.
if (formErrors !== {}) {
displayFormErrors(formErrors);
event.preventDefault();
}
else {
clearForm();
}
I've tried multiple ways and nothing has worked so far. Any help is appreciated, thank you!
EDIT
I can't use the .length on the array cause the length is 0 even when it has data.
Screenshot of chrome debugger
I'm slightly confused about what people are asking sorry, i'm not an expert here is my full code to get a better understanding of what i'm trying to do.
$(document).ready(function () {
$('#submit').on("click", onSubmitForm);
function onSubmitForm(event) {
clearErrorMessages();
var formData = getFormData();
var formErrors = validateFormData(formData);
if (formErrors) {
displayFormErrors(formErrors);
event.preventDefault();
}
else {
clearForm();
// Do other stuff
}
}
function clearForm() {
$('#title').val("");
$('#client').val("");
$('#date').val("");
$('#status').val("planning");
$('#description').val("");
$('.type').prop('checked', false);
$('.extra').prop('checked', false);
$('#title').focus();
}
function clearErrorMessages() {
$(".uk-text-danger").html("");
}
function getFormData () {
var data = [];
data["title"] = $('#title').val();
data["client"] = $('#client').val();
data["date"] = $('#date').val();
data["status"] = $('select#status option:selected').val();
data["description"] = $('#description').val();
if ($("input[name='type']:checked").length > 0) {
data["type"] = $("input[name='type']:checked").val();
}
else {
data["type"] = "";
}
data["extras"] = [];
$.each($("input[name='extras[]']:checked"), function(index, radio) {
data["extras"].push(radio.value);
});
return data;
}
function validateFormData(data) {
var errors = [];
if (data["title"].length == 0) {
errors["title"] = "Project title required";
}
if (data["client"].length == 0) {
errors["client"] = "Client name required";
}
if (data["date"].length == 0) {
errors["date"] = "Date required";
} else if (!isValidDateFormat(data["date"])) {
errors["date"] = "Date format invalid - Format: dd/mm/yyyy";
}
if (data["status"] == "") {
errors["status"] = "Please select current status for this project";
}
if (data["type"] == "") {
errors["type"] = "Please select a project type";
}
if (data["extras"].length == 0) {
errors["extras"] = "You must select at least one extra for this project";
}
return errors;
}
function displayFormErrors(errors) {
for (var field in errors) {
var errorElementId = field + "Error";
$('#' + errorElementId).html(errors[field]);
}
} });
Sorry if this is too much i'm not sure what else to do.
An empty array, string or object is "falsy" in JavaScript.
That is, you can pass the array, string or object directly into the if conditional and it will run depending on if something is in there or not.
if ([]) {
// this will never run
}
if ('') {
// this won't run either
}
if ({}) {
// nor will this
}
var errors = {}; inside the validateFormData function.
And then compare the the object like this.
if (JSON.stringify( formErrors ) !== '{}') { //do something}else { //do something}
Where are you verifying if the formErrors is empty? This verification (the if-else) should be inside the function which submits the form.
Also try using:
if (formErrors.length > 0)
instead of:
if (formErrors !== {})

JavaScript if else statements to display html label

I have a log in form and am trying to display an error message if the log is incorrect.
For example;
If (email and password match) then set validUser to true.
If validUser equals true then redirect to home page
Else redirect them back to log in and display one of 3 messages...
Messages are:
'Log in unsuccessful' if both email and password are incorrect
'Password incorrect' if just the password is wrong
'Email incorrect' if just the email is wrong
Is it possible to have a loop to do all this? I can't figure it out....
Trying something like this too:
if (validUser==false)
{
$("message").show();
}
else if ( ..........)
{
$("passwordmessage").show();
}
I also want to display a message on the page and so far using this:
document.getElementById('message').style.display = ""
Here is my code: http://jsfiddle.net/2pkn1qrv/
So, how could I use if statements to do this and how can I correctly display a html page element using javascript or jquery?
Please ask if you need any more code or require clarification.
P.s. these are my users details
var USERS = {
users: []
};
function User(type, email, password) {
this.type = type;
this.email = email;
this.password = password;
}
var A = new User("rep", "a#a.com", "a");
USERS.users.push(A);
var B = new User("rep", "b#b.com", "b");
USERS.users.push(B);
var C = new User("customer", "c#c.com", "c");
USERS.users.push(C);
var D = new User("grower", "d#d.com", "d");
USERS.users.push(D);
module.exports = USERS;
You wont be having 3 conditions in that case. you will check email availability and password match. If anyone fails, you can display the message. I couldnt test your code but this will be the logic and i assume Users.user[x].email is the list of emails from your database. If yes, sorry to say that its a bad practise.
validUser = false;
emailAvailable = false;
passwordIncorrect = false;
for (var x in USERS.users) {
if(!emailAvailable && emailLog === USERS.users[x].email){
emailAvailable = true;
} //Checks whether email is available.
if(emailAvailable && passwordLog === USERS.users[x].password){
passwordIncorrect = true;
break;
} //Checks whether the password is correct for that email.
} // end of for
if(!emailAvailable){
console.log("Email is incorrect");
}
else if(emailAvailable && !passwordIncorrect){
console.log("Password is incorrect");}
else{
validUser = true;
console.log("Valid User");
}
if(validUser){
//redirect
}
I think my way is it worth to give a try:
First: create a Javascriptobject:
function ruleToCheck(errorRule, errorMsgContainer)
{
this.errorCondition = errorRule;
this.errorMessage = errorMsgContainer;
}
after that create an array and fill it with your rules:
var rulesList = new Array();
rulesList.push(new ruleToCheck("validUser === true", "message"));
...
Then loop through the array:
var rulesListLength = rulesList.length;
var index = 0;
while (index < rulesListLength)
{
index++;
...
}
The secret of success is the powerful eval() function within the while() loop:
if (eval(rulesList[index].errorCondition))
{
$("#"+rulesList[index].errorMessage).show();
break;
//If 'break does not work, use 'index = rulesListLength'
}
Hope it was helpful or at least leaded you into the right direction.
By the way, take care of the comments on your question.

Categories