0

i'm trying to throw together a simple javascript page with multiple if statements. the idea is to append to a list based on the evaluation of a stack of if statements. the problem is if any one of them fails, it triggers the else statement. i only want it to trigger else in the case that all of them fail.

<p id="fruit">My fruit basket has: </p>

if (apples) {
        document.getElementById("fruit").innerHTML += "apples";
    }
if (oranges) {
        document.getElementById("fruit").innerHTML += "oranges";
    }
if (bananas) {
        document.getElementById("fruit").innerHTML += "bananas";
    }
else {
        document.getElementById("fruit").innerHTML += "nothing";
}

when i run this and all conditions are met, i'll get:

My fruit basket has: apples oranges bananas

when i run this and no conditions are met, i'll get:

My fruit basket has: nothing

but if any one of the conditions is not met, i'll get:

My fruit basket has: apples nothing

or

My fruit basket has: apples bananas nothing

i've tried using if else, but then it quits after the first 'match'. so in the above example if i have both apples and bananas, using if else will return

My fruit basket has: apples

and not tell me i also have bananas.

question: how do i do this so the else statement is only run in the case that all if statements have failed?

EDIT i tried to make this as simple as i could, but it seems i over simplified it.

the else nothing isn't known until all the if statements have been run. that's literally it's condition: if all the ifs fail.

i tried using the OR operator and it just broke everything. in my code, what's actually happening at if (apples) is it's checking today's date to see if it falls within a range of dates. it needs to do this for a whole bunch of different fruit based on a schedule that is pretty complicated, i.e. figuring out exactly which fruit are in the basket on a given day is harder than just running the schedule against these if 'rules'.

	var isSunday = new Date().getDay();
	var apples1Start = new Date(2018,8,4); // sept 4, 0 == jan.
	var apples1Stop = new Date(2018,8,23); // sept 22, stop dates need to be day after.
	var apples2Start = new Date(2018,10,5); // nov 5
	var apples2Stop = new Date(2018,10,25); // nov 24
	var apples3Start = new Date(2018,10,26); // nov 26
	var apples3Stop = new Date(2018,11,9); // dec 8
	var oranges1Start = new Date(2018,3,30); // april 30
	var oranges1Stop = new Date(2018,4,27); // may 26
	var oranges2Start = new Date(2018,9,22); // oct 22
	var oranges2Stop = new Date(2018,10,4); // nov 3
	var oranges3Start = new Date(2018,3,28); // april 28
	var oranges3Stop = new Date(2018,3,29); // april 28
	var bananas1Start = new Date(2018,0,1); // jan 1
	var bananas1Stop = new Date(2018,3,10); // april 9
	var bananas2Start = new Date(2018,6,2); // july 2
	var bananas2Stop = new Date(2019,3,11); // april 10
	var kiwi1Start = new Date(2018,9,13); // oct 13
	var kiwi1Stop = new Date(2018,10,25); // nov 24
	var papaya1Start = new Date(2018,8,29); // sept 29
	var papaya1Stop = new Date(2018,8,30); // sept 29
	var papaya2Start = new Date(2018,10,1); // nov 1
	var papaya2Stop = new Date(2018,10,4); // nov 3
	var papaya3Start = new Date(2018,9,15); // oct 15
	var papaya3Stop = new Date(2018,10,25); // nov 24
	var papaya4Start = new Date(2018,10,26); // nov 26
	var papaya4Stop = new Date(2018,11,9); // dec 8
	var papaya5Start = new Date(2018,11,10); // dec 10
	var papaya5Stop = new Date(2019,1,1); // dec 31
	var clemantines1Start = new Date(2018,0,1); // jan 1
	var clemantines1Stop = new Date(2018,2,1); // feb 28
	var clemantines2Start = new Date(2018,9,13); // oct 13
	var clemantines2Stop = new Date(2019,1,29); // feb 28
	var pears1Start = new Date(2018,8,10); // sept 10
	var pears1Stop = new Date(2019,0,3); // jan 2
	var tangerines1Start = new Date(2018,0,1); // jan 1
	var tangerines1Stop = new Date(2018,2,9); // mar 8
	var tangerines2Start = new Date(2018,11,20); // dec 20
	var tangerines2Stop = new Date(2019,2,9); // mar 8
	var starfruit1Start = new Date(2018,0,1); // jan 1
	var starfruit1Stop = new Date(2018,2,9); // mar 8
	var starfruit2Start = new Date(2018,9,13); // oct 12
	var starfruit2Stop = new Date(2019,2,9); // mar 8
	var lemons1Start = new Date(2018,0,1); // jan 1
	var lemons1Stop = new Date(2018,2,1); // feb 28
	var lemons2Start = new Date(2018,10,1); // nov 1
	var lemons2Stop = new Date(2019,2,1); // feb 28
	var apricots1Start = new Date(2018,0,1); // jan 1
	var apricots1Stop = new Date(2018,1,1); // jan 31
	var apricots2Start = new Date(2018,9,1); // oct 1
	var apricots2Stop = new Date(2019,1,1); // jan 31
	var tomatoes1Start = new Date(2018,0,1); // jan 1
	var tomatoes1Stop = new Date(2018,1,1); // jan 31
	var tomatoes2Start = new Date(2018,9,1); // oct 1
	var tomatoes2Stop = new Date(2019,1,1); // jan 31
	var today = new Date();

function yarp() {
	document.body.style.background = "green";
	document.getElementById("main").innerHTML = "you have fruit";
}

function narp() {
	document.body.style.background = "#ffffff";
	document.getElementById("main").innerHTML = "nothing";
}

	if (isSunday == 0) {
		document.body.style.background = "#ffffff";
		document.getElementById("main").innerHTML = "sunday";
		document.getElementById("fruit").innerHTML = "no fruit on a sunday.";
	}

	else {
		if (today >= apples1Start && today <= apples1Stop || today >= apples2Start && today <= apples2Stop || today >= apples3Start && today <= apples3Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "apples! ";
		}
		if (today >= oranges1Start && today <= oranges1Stop || today >= oranges2Start && today <= oranges2Stop || today >= oranges3Start && today <= oranges3Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "oranges. ";
		}
		if (today >= bananas1Start && today <= bananas1Stop || today >= bananas2Start && today <= bananas2Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "bananas. ";
		}
		if (today >= kiwi1Start && today <= kiwi1Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "kiwi. fancy! ";
		}
		if (today >= papaya1Start && today <= papaya1Stop || today >= papaya2Start && today <= papaya2Stop || today >= papaya3Start && today <= papaya3Stop || today >= papaya4Start && today <= papaya4Stop || today >= papaya5Start && today <= papaya5Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "papaya. ";
		}
		if (today >= clemantines1Start && today <= clemantines1Stop || today >= clemantines2Start && today <= clemantines2Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "clemantines. ";
		}
		if (today >= pears1Start && today <= pears1Stop) {
			yarp();
			document.getElementById("fruit").innerHTML += "pears. ";
		}
		if (today >= tangerines1Start && today <= tangerines1Stop || today >= tangerines2Start && today <= tangerines2Stop ) {
			yarp();
			document.getElementById("fruit").innerHTML += "tangerines. ";
		}
		if (today >= starfruit1Start && today <= starfruit1Stop || today >= starfruit2Start && today <= starfruit2Stop ) {
			yarp();
			document.getElementById("fruit").innerHTML += "star fruit. ";
		}
		if (today >= lemons1Start && today <= lemons1Stop || today >= lemons2Start && today <= lemons2Stop ) {
			yarp();
			document.getElementById("fruit").innerHTML += "lemons. ";
		}
		if (today >= apricots1Start && today <= apricots1Stop || today >= apricots2Start && today <= apricots2Stop ) {
			yarp();
			document.getElementById("fruit").innerHTML += "apricots. ";
		}
		if (today >= tomatoes1Start && today <= tomatoes1Stop || today >= tomatoes2Start && today <= tomatoes2Stop ) {
			yarp();
			document.getElementById("fruit").innerHTML += "tomatoes. ";
		}
		
		else {
			narp();
		}
	}
#horizon {
	position: absolute;
	top: 50%;
	width: 100%;
}

#content {
	position: absolute;
	top: -63px;
	text-align: center;
	width: 100%;
}

#main {
	line-height: 75px;
	font-size: 100px;
	margin: 0;
}
<div id="horizon">
	<div id="content">
		<h1 id="main"></h1>
		<p id="fruit"></p>
	</div>
</div>

4
  • Please post a Minimal, Complete, and Verifiable example Commented Mar 8, 2018 at 22:11
  • 1
    Make these separate if statements with no else branches. Commented Mar 8, 2018 at 22:12
  • I think this is a complete, minimal example Commented Mar 8, 2018 at 22:12
  • Have you tried your code with just "bananas"? Commented Mar 8, 2018 at 22:14

4 Answers 4

3

Use the negation operator to check the nothing case.

if (!(apples || oranges || bananas)) {
  document.getElementById("fruit").innerHTML = "nothing";
  return; // Assuming this code is inside of a function.
}

if (apples) {
  document.getElementById("fruit").innerHTML += "apples";
}

if (oranges) {
  document.getElementById("fruit").innerHTML += "oranges";
}

if (bananas) {
  document.getElementById("fruit").innerHTML += "bananas";
}
Sign up to request clarification or add additional context in comments.

2 Comments

Wasn't me, but top-level return maybe? Uncaught SyntaxError: Illegal return statement
I don't understand why is this being downvoted? It's a clean and concise answer.
2

Separate the if statements so that the branches are not mutually exclusive and set up a "result" variable with a default value prior to testing.

Side Notes:

  • String.indexOf(str) is a way to check for a string's position within another string. It returns the index position that the search string was found at or -1 if the string wasn't found at all. It's a great way to test for the existence of a substring.
  • Only update the web page elements when absolutely necessary (i.e. setting .innerHTML) because it's an expensive operation. Instead, you can prepare what you want to write out in a string ahead of time and then, once the string is completely built, inject it into the page just once.
  • .innerHTML is used when the string you are getting/setting contains HTML that needs to be parsed as such. When your string doesn't contain any HTML, it's wasteful to use this because you are asking the HTML parser to look for and process HTML that it's not going to find. In these cases, use .textContent because it bypasses the HTML parser and is more efficient.

var out = document.getElementById("output");

function fruit(type){

  // Set type to an empty string if it is undefined
  type = type || "";

  // Set a default value first
  var result = "";

  if (type.indexOf("apples") > -1) {
    result = "apples";
  }

  if (type.indexOf("oranges") > -1) {
    result += " oranges";
  }

  if (type.indexOf("bananas") > -1) {
    result += " bananas";
  }
  
  // If the result is still an empty string, nothing correct was passed
  if(!result){
    result = "nothing";
  }
 
  // Now write out the final value of the variable
  // and only use .innerHTML when you are writing HTML,
  // otherwise, use .textContent
  out.textContent = result;
 
}

fruit();                  // My fruit basket has: nothing
fruit("apples");          // My fruit basket has: apples
fruit("oranges");         // My fruit basket has: oranges
fruit("bananas");         // My fruit basket has: bananas
fruit("apples oranges");  // My fruit basket has: apples oranges
fruit("apples bananas");  // My fruit basket has: apples bananas
<p id="fruit">My fruit basket has: <span id="output"></span></p>

5 Comments

This doesn't seem very DRY.
@PatrickRoberts No, it's not. But, the question was not how to refactor the code to be the most efficient. The question was how to use if statements without an else to produce the desired result. As a result, it should not be down voted.
Also, no idea who is serial downvoting. It's getting a bit ridiculous
This answer doesn't deserve a dowmvote. Upvoted to rollback that -1
thanks scott. this was really helpful. also, GTK on the .textContent vs .innerHTML.
1

You can just combine these statements using the or || separator and catch every other case:

Syntax: if (apples || oranges || bananas) {} if apples or oranges or bananas

Syntax: if (apples && oranges && bananas) {} if apples and oranges and bananas

Syntax: if ( (apples && oranges) || bananas) {} if apples and oranges or just bananas

var apples = false, oranges = false, bananas = false

var count=0 // just for displaying different fruits
function switchFruit() {
 
  if (count == 1) {apples=true; oranges=false, bananas=false, button.value="apple"}
  if (count == 2) {apples=false; oranges=true, bananas=false, button.value="oranges"}
  if (count == 3) {apples=false; oranges=false, bananas=true, button.value="bananas"; count=0}
  
  count++;
  
  if (apples || oranges || bananas) { // if apples or oranges or bananas
    if (apples) {
      document.getElementById("fruit").innerHTML += "apples ";
    }
    if (oranges) {
      document.getElementById("fruit").innerHTML += "oranges ";
    }
    if (bananas) {
      document.getElementById("fruit").innerHTML += "bananas ";
    }
  } else { // if not one of "apples, oranges, bananas"
    document.getElementById("fruit").innerHTML += "nothing ";
  }
}
<input type="button" id="button" onclick="switchFruit()" value="nothing">

<p id="fruit"></p>

Have a look at logical operators in the docs

3 Comments

@anonymous down voter. Share your thoughts to us all please :)
I got an upvote & a down vote - crazy world :p @MikeMcCaughan
Maybe shouldiblamecaching.com, but when I look at the spread of votes (something you get at 1000 rep), I see 0 up and 0 down. Yeah, I'll blame caching...
0

There are multiple ways to do this. I'm partial to adding a variable to keep track of whether or not any of the ifs returned true:

var empty = true;
if(apples) {
    innerHTML += "apples";
    empty = false;
}
if(oranges) {
    innerHTML += "oranges";
    empty = false;
}
if(bananas) {
    innerHTML += "bananas";
    empty = false;
}
if(empty) {
    innerHTML += "nothing";
}

Alternatively, you could figure out if its empty based on the length of the added string:

var str = "";
if(apples) {
    str += "apples";
}
if(oranges) {
    str += "oranges";
}
if(bananas) {
    str += "bananas";
}
if(str.length == 0) {
    str = "nothing";
}

innerHTML += str;

2 Comments

var empty = !(apples || oranges || bananas); no need to assign it inside each if statement. (FYI, didn't downvote)
Yea, there are multiple ways of doing it. I wrote the first example with the intention of never needing to write the fruit names more than once (or twice if you include the string versions).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.