How to nest an if-statement inside a function? - Javascript - javascript

Now that I have a recursive function, I wonder what is best in order for the same flow to continue.
Nest an another function, isn't it?
In other words, I would like another prompt that asks the user's age when the user answers yes to the first prompt.
The issue that I'm facing now is that the last prompt does not comeback if the user writes something different than "yes" or "no".
They way I've nested it makes the prompts pop up in a way that I can't figure out:
function showPrompt(msg) {
var str = prompt(msg).toLowerCase();
if (str === "yes") {
function showPrompt(firstQuestion) {
var age = prompt(firstQuestion).toLowerCase();
if (age < 21) {
alert("You're too young. Go home.");
} else if (age >= 21) {
alert("Welcome.");
} else {
showPrompt(firstQuestion);
}
}
showPrompt("How old are you?");
} else if (str === "no") {
alert("goodbye.");
} else {
showPrompt(msg);
}
}
showPrompt("Do you like gambling?");

The problem is that you are overwriting your function. If you give your second function another name I guess it works the way you want. And as given in the other answer, you do not need to define your function in the condotional clause:
function showPrompt(msg) {
var str = prompt(msg).toLowerCase();
if (str === "yes") {
nextQuestion("How old are you?");
} else if (str === "no") {
alert("goodbye.");
} else {
showPrompt(msg);
}
}
function nextQuestion(secondQuestion) {
var age = parseInt(prompt(secondQuestion));
if (typeof age == "number" && age < 21) {
alert("You're too young. Go home.");
} else if (typeof age == "number" && age >= 21) {
alert("Welcome.");
} else {
showPrompt(secondQuestion);
}
}
showPrompt("Do you like gambling?");

Your problem is the conditional creation of showPrompt within the function called showPrompt, see Function declarations inside if/else statements?. While such declarations are allowed, they have side effects and should be avoided.
One side effect is that the conditional function declaration creates a local variable that is undefined unless execution enters the if block and assigns it a value. In the OP, the local showPrompt declaration shadows the global showPrompt created by the global function declaration. Hence if the block is not entered, when it's called, its value is undefined and a TypeError is thrown, e.g.
// Global foo
var foo = 23;
function bar() {
// Declaration creates a local foo even if
// if block is not entered
if (false) {
function foo (){}
}
// foo is undefined
console.log(typeof foo);
}
bar();
To fix that, change the name of the function in the if block and move it out of the block.
Also, as pointed out by epascarello, you should do numeric comparisons using numbers, not strings. When using comparison operators, if one of the values is a number, then the other will be converted to number too for the comparison. But if they are both strings (prompt returns a string), they'll be compared as strings. But for readability, it's best to use numbers for both sides.
Finally, you should test the value returned by the prompt to see it's a string. If the user clicks "Cancel", it will return null and calling toLowerCase will throw an error. So if the value isn't a string, the user clicked cancel and the function should handle it (e.g. exit).
function showPrompt(msg) {
function showPrompt2(firstQuestion) {
var age = prompt(firstQuestion);
if (typeof age != 'string') {
return;
}
if (+age < 21) {
alert("You're too young. Go home.");
} else if (+age >= 21) {
alert("Welcome.");
} else {
showPrompt2(firstQuestion);
}
}
var str = prompt(msg);
if (typeof str != 'string') {
return;
}
str = str.toLowerCase();
if (str === "yes") {
showPrompt2("How old are you?");
} else if (str === "no") {
alert("goodbye.");
} else {
showPrompt(msg);
}
}
showPrompt("Do you like gambling?")

Related

if statement is not returning expected result Javascript

I wrote a small script after learning a bit about the object constructor and I wanted to take it a step further with this code, but the if statement isn't behaving as expected... All I want to know is why? I understand this kind of script isn't a normal thing in Javascript... but I believe that the === is evaluating to true, thus printing dave in the alert box, no matter what I enter, and not following through the if statement conditions.
var dave, jason, nick, get;
get = prompt('Input your Name', 'Name Here')
var Person = function (name, birthYear, job) {
this.name = name;
this.birthYear = birthYear;
this.job = job;
};
dave = new Person('Dave', 1976, 'Showman');
jason = new Person('Jason', 1987, 'Novice');
nick = new Person('Nick', 1993, 'Cable-tech');
function printObj(object) {
var output = '';
for (var property in object) {
output += property + ': ' + object[property] + '\n';
}
alert(output);
}
if (get.toLowerCase === 'dave'.toLowerCase) {
printObj(dave);
} else if (get.toLowerCase === 'jason'.toLowerCase) {
printObj(jason);
} else if (get.toLowerCase === 'nick'.toLowerCase) {
printObj(nick);
} else {
alert('Not a defined object')
}
Something else obvious I might be doing wrong is the comparison... but that's how it was explained to me in javascript on freenode, because at first that was my issue, which is still kind of it I suppose. I think I'm simply doing something obviously messy, appreciate any insight I receive, the MDN and W3 only explain so much.
get.toLowerCase() is a method, and should be invoked with the open and closed parenthesis. The way it is currently written is checking whether the method is equal to the same method on a different string instance.
if (get.toLowerCase() === 'dave') {
printObj(dave);
} else if (get.toLowerCase() === 'jason') {
printObj(jason);
} else if (get.toLowerCase() === 'nick') {
printObj(nick);
} else {
alert('Not a defined object')
}
Since you are comparing to a lowercase string, you don't need to call toLowerCase() on 'dave', 'jason', or 'nick'. I think you may have meant to compare to the value stored in the variables dave, jason, and nick.
if (get.toLowerCase() === dave.name.toLowerCase()) {
printObj(dave);
} else if (get.toLowerCase() === jason.name.toLowerCase()) {
printObj(jason);
} else if (get.toLowerCase() === nick.name.toLowerCase()) {
printObj(nick);
} else {
alert('Not a defined object')
}
Last, you should not name a variable get. get is reserved in ES6 so as browser start to natively support it, your code will do some very odd things. I suggest something like userInput.
var dave, jason, nick, userInput;
userInput = prompt('Input your Name', 'Name Here')
//...other code...
if (userInput.toLowerCase() === dave.name.toLowerCase()) {
printObj(dave);
} else if (userInput.toLowerCase() === jason.name.toLowerCase()) {
printObj(jason);
} else if (userInput.toLowerCase() === nick.name.toLowerCase()) {
printObj(nick);
} else {
alert('Not a defined object')
}
You are using the .toLowerCase() method the wrong way. Also, you are using the get
Your Code:
var dave, jason, nick, get;
get = prompt('Input your Name', 'Name Here')
// other code
if (get.toLowerCase === 'dave'.toLowerCase) {
printObj(dave);
} else if (get.toLowerCase === 'jason'.toLowerCase) {
printObj(jason);
} else if (get.toLowerCase === 'nick'.toLowerCase) {
printObj(nick);
} else {
alert('Not a defined object')
}
As you can see on your code your .toLowerCase method misses the (). And please do not use the get as a variable name because get is a keyword.
Try this:
var dave, jason, nick, inputValue;
inputValue = prompt('Input your Name', 'Name Here')
// other code
if (inputValue.toLowerCase() === 'dave'.toLowerCase()) {
printObj(dave);
} else if (inputValue.toLowerCase() === 'jason'.toLowerCase()) {
printObj(jason);
} else if (inputValue.toLowerCase() === 'nick'.toLowerCase()) {
printObj(nick);
} else {
alert('Not a defined object')
}
Also, if you are comparing an own defined comparison there's no need to add the .toLowerCase(). You actually want to compare the input value (which is an unknown format ei. upper case or lower case) to a lower case string value that you want to compared of.
Use this:
if (get.toLowerCase === 'dave')
instead of
if (get.toLowerCase === 'dave'.toLowerCase())

Why won't this specific function work?

Create a function called whichChild that takes one parameter: a child's name.
When passed in ‘Dave’ return ‘Oldest’
When passed in ‘Michelle’ return ‘Middle’
When given any other value return ‘Not my kid!”
function whichChild(achildsname){
var name = prompt ("Which Child?");
if (name == "Dave") {
prompt("Oldest");
}
else if (name == "Michelle"){
prompt("Middle");
}
else (name /= "Dave" && "Michelle"){
prompt("Not My Kid!");
}
}
Ok redo! How am I supposed to make this function take one parameter? I need it to take one parameter: a child's name. Im supposed to create this function for a test. Any help would be much appreciated. Thank you.
function whichChild(){
var name = prompt("Which Child?");
if (name === "Dave") {
console.log("Oldest");
}
else if (name === "Michelle"){
console.log("Middle");
}
else {
console.log("Not My Kid!");
}
}
whichChild();
You don't need the parameter, because there is no need of calling an argument in the function. Instead of prompt, use console.log, I assume you are trying to display a message after the user has prompted a name, so, it would not be appropriate to have a prompt after another prompt, when the only thing you need is a response,"whichChild();" will invoke that function.
I believe this is what you want:
function whichChild() {
var name = prompt("Which Child?");
if (name == "Dave") {
alert("Oldest");
} else if (name == "Michelle") {
alert("Middle");
} else {
alert("Not My Kid!");
}
}
whichChild();

JavaScript If string is equal to anything else

How do I check if a string is not equal to any of the other options? I know I can just do a simple else statement, but I'm not sure if it'll work since the code in my ifs aren't combined, yet they are just if() and else if() for its own, but then no else. How could I do a else statement/check if its anything else without using a switch/case statement?
Here's an example.
if(object1 === "string") {
function1();
}
if(object1 === "string2") {
function2();
if(object2 === "string" && variable === 10) {
function1();
}
if(object1 || object2 === "") {
alert("That's not a valid option!");
}
WARNING
I can't insert the code here as standalone or snippet, due to it exceeding the maximum character limit. I am only able to add a JSFIDDLE. Please excuse the inconvienence.
JSFIDDLE
The two main ways you can do it without if/else if/else being combined are a simple fall through
function foo(opt) {
if (opt === 'this') { return true; }
if (opt === 'that') { return 'something else'; }
/* Code here represents the case that opt is not this or that */
}
Another more complex way of doing it would be to have some kind of array of options and then checking them all but it's a bad pattern and you really should consider using if/else if/else as a combined tree (not sure you've really explained why you can't do this.
function foo(opt) {
var checked = ['this', 'that'];
if (opt === 'this') { return true; }
if (opt === 'that') { return 'something else'; }
if (checked.indexOf(opt) === -1) { return 'fall through case'; }
}
A switch is also possible but that's just a variation of a combined if/else if/else so if you can't use the latter I don't see how the former would help
Again the above is a bad pattern but if for some reason that's what you have to then there's an implementation.
Another solution would be to raise flags when going through one of the if statement, so that at the end, you can check those flags and if none are true, then you can do whatever you want.
var flag = false;
if(object1 === "string") {
function1();
flag = true;
}
if(object1 === "string2") {
function2();
flag = true;
if(object2 === "string" && variable === 10) {
function1();
flag = true;
}
if(object1 || object2 === "") {
alert("That's not a valid option!");
flag = true;
}
if(!flag) {
alert('no other options were validated');
}

function not visible in function expressions, how to fix this?

I have a function expression like this :
var inputChecker = function(field) {
return function() {
if(field === '' || field === 'undefined' || field === null) {
return false;
}
return true;
}
}
that I want to use in several different function expressions :
(function($) {
if(inputChecker(x)) {}
})(jQuery);
(function($) {
})(jQuery);
But the problem is inputChecker is not visible in these function expressions when it's declared out of their bodies ? I don't understand why? Isn't inputChecker supposed to be global ?
Dystroy's answer is definitely simpler. But if you want it your way...
The return value of the inputChecker is a function, not boolean. If you want to call the returned function, use () expression:
var fn = inputChecker(x); // gets the function
fn(); // calls the returned function
or shorter
inputChecker(x)();
In your code
(function($) {
if(inputChecker(x)()) {
// custom code here if x is defined
}
})(jQuery);
Note: if you want to check if variable is not undefined, strip the apostrophes - undefined is constant, not string
if(field===undefined)
What you wrote is a function factory. It doesn't return a boolean but a function able to check a property.
This kind of functions is sometimes useful but :
you're here, in the returned function, checking the value of the property received by the factory. As this value can't change (it's embedded in the closure), the produced function holds no more information than just true or false. So it's useless.
you're calling inputChecker(x) as if it was a boolean instead of a function.
So what you probably want is simply
var checkInput = function(field) {
if(field === '' || field === 'undefined' || field === null){
return false;
}
return true;
}
But if you really want to generate different checking functions, dependent on another value, you could use the function factory pattern like this:
var x = true;
var checkInput = (function (x) {
if (x === true) {
return function(field) {
if(field === '' || field === 'undefined' || field === null){
return false;
}
return true;
}
} else {
return function(field) {
//evaluate field differently
}
}
}(x));
Now, dependig on what x is, one or another function will be assigned to checkInput.

Javascript if clause won't work

I'm having trouble with a javascript function that needs to take a global variable into account.
It's kind of a control mechanism I would like to implement, but I can't seem to get it right.
Here's the relevant code
<script type="text/javascript">
var active = 0;
function SetEndTime(lngOpenPersonID,lngToDoID){
if(active = 0){
alert('Time has been stopped');
}
else{
var strURL = 'blabla';
CallAJAXURL(strURL);
}
active = 0;
}
function SetStartTime(lngToDoID,lngToDoItemID,bitCountsForTotal){
if(active = 1){
alert('Time has been started');
}
else{
var strURL = 'blabla';
CallAJAXURL(strURL);
}
active = 1;
}
When I call SetStartTime without doing anything else, I always get the alert. Is there something wrong with my syntax?
if (active == 0) {
You need 2 "=" characters to make a comparison operator. There's also === which performs an equality comparison without type promotion.
Your code is syntactically correct because an assignment operation is a valid expression. The first if statement you had:
if (active = 0) {
will never be true, because the value of the expression is always zero. The second one:
if (active = 1) {
conversely is always true because the value is always one.
its not (alert = 1) .. its ( alert == 1 ).. your condition says its always true -- your assigning alert to 1

Categories

Resources