c

How to shorten conditionals with ternaries

If / else statements are readable

If and else statements are great for what's known as flow control, in other words, for establishing what happens in our application based on one condition or another.

If / else statements are very easy to read and understand what is happening, for example, if we have authentication in our app and are authenticating our app users, we might want to check if we have an authenticated user, and if so, enable them to do one thing, like add an item to their cart, else if they are not authenticated, to do something else entirely, like tell the user to login.

const isAuthenticated = false;
let cartItemCount = 0;
if (isAuthenticated) {
  // add item to cart
  cartItemCount = 1;
} else {
  // tell user to login
  console.log("Please log in!");
}

Ternary for conditionally assigning variables

But what if we want to do something very simple, such as conditionally give a value to a variable? Let's say that if a user is authenticated, set cartItemCount to 1, as we are doing here, otherwise, we set it to 0:

const isAuthenticated = false;
let cartItemCount = 0;
if (isAuthenticated) {
  // add item to cart
  cartItemCount = 1;
} else {
  // tell user to login
  // console.log("Please log in!");
  cartItemCount = 0;
}

We have to repeat ourselves by saying cartItemCount two or more times, say if we had more conditions. Try to imagine if we needed to conditionally set multiple variables. In programming, we want to try not to repeat ourselves. If you find yourself having to repeat the same operation many times, over and over, try to look for alternative. There's usually a better pattern to follow.

Fortunately there is a better way to do this--to conditionally set the value of a variable without repeating ourselves and by using less code. We do so by using a new operator called a ternary operator.

We can simplify our code by replacing the if part along with it's parentheses with first the value we want to apply the condition to, in this case isAuthenticated, and afterwards, add a ?

const isAuthenticated = false;
// let cartItemCount = 0;
// if (isAuthenticated) {
//   // add item to cart
//   cartItemCount = 1;
// } else {
//   // tell user to login
//   // alert("Please log in!");
//   cartItemCount = 0;
// }

isAuthenticated ?

So if this first part replaces the if part, and right after the ? is the then part, which is what we want to happen if the condition resolves to true.

Looking back at our previous code, when isAuthenticated was true, cartItemCount was being updated to 1. So here's the special thing about ternaries in relation to variables--we don't have to immediately assign it to the variable. Unlike if statements, we don't have to say if isAuthenticated is true, set cartItemCount is equal to 1:

isAuthenticated ? cartItemCount = 1

Instead, we can remove the reference to the variable in this part, called the 'then' part of the conditional, and instead move it to the beginning:

const cartItemCount = isAuthenticated ? 1

This is because a ternary is an expression, instead of a statement. In other words, it resolves to a value and whenever it runs, it returns a value. So our conditional runs, and isAuthenticated is true, the then part runs and it is returns the value 1. It resolves to the value 1 and since this is all an expression, it can be immediately put in our cartItemCount variable, so we only have to reference it once, when it's declared.

But what about the else condition, if isAuthenticated is false. This part of the conditional is put after another special symbol, the colon:

const cartItemCount = isAuthenticated ? 1 :

And after the colon is where we jump to if our ternary's condition resolves to false.

So looking at our if statement from before in the else area, we were setting cartItemCount to 0. So since we know our ternary returns the value it resolves to, we can just put 0 in our else condition and it will immediately be put in our cartItemCount variable as well.

const cartItemCount = isAuthenticated ? 1 : 0;

So finally, let's console log cartItemCount and see what we get. But before we do, if isAuthenticated is set to true, so what do you think the value of cartItemCount will be?

const isAuthenticated = true;

const cartItemCount = isAuthenticated ? 1 : 0;
console.log(cartItemCount); // 1

[Run code] We get 1. isAuthenticated resolves to true in our condition, therefore the then condition runs and 1 is implicitly returned and assigned to cartItemCount.

And if we update isAuthenticated to false:

const isAuthenticated = false;

const cartItemCount = isAuthenticated ? 1 : 0;
console.log(cartItemCount); // 0

[Run code] We get zero. isAuthenticated is false in our condition, then the else condition runs and 0 is put in cartItemCount.

And finally, what if instead of just returning a value, we also wanted to do something like we did before, where we were alerting the user to login:

const isAuthenticated = false;

const cartItemCount = isAuthenticated ? 1 : console.log("Please log in");
console.log(cartItemCount);

[Run code] We see our alert, but what happens to cartItemCount? It now has the value undefined instead of 0, which is wrong.

So know that ternaries are very helpful in some situations, but they shouldn't be used all the time for every conditional you have to write

Help us to easily conditionally assign a variable without repetition, but if you want to perform multiple actions or do something that doesn't give us a return value, use a normal if statement like we had before.

Another example

Let's use another example, where we want to greet a user based on their age.

So let's say we are getting their age from an input or a form, and we're putting the result in a variable called age. Let's say it's 20:

const age = 20;

And then we want to create a customer greeting for our users based on their age. So we'll use an if statement to create this condition. We'll conditionally store the greeting text in a variable called greeting. And for now, we'll just have one condition. If the age is less than 10, we'll say "Hey there". Otherwise, if they are any other age, else, we'll say "That's an interesting age"

let greeting;
if (age < 10) {
  greeting = "Hey there";
} else {
  greeting = "That's an interesting age!";
}
console.log(greeting);

So now take a minute, using the if statement we have here and convert it to a ternary.

Our ternary has three parts. First we'll begin by adding our conditional, which will resolve to a boolean value, true or false. In our case, we need to see if age is less than 10. If that's true, we want the value of the greeting to be 'Hey there'. And if this condition resolves to false, the value should be 'That's an interesting age'. And we want to conditionally update the variable greeting:

// let greeting;
// if (age < 10) {
//   greeting = "Hey there";
// } else {
//   greeting = "That's an interesting age!";
// }

const greeting = age < 10 ? "Hey there" : "That's an interesting age!";
console.log(greeting);

So let's run this an input our own age.

[Run code] So the benefit here, like in the example we saw before is that we can use const instead of let, which isn't possible to be changed after being initialized. Since we know how const and let operate, we can see that this is a big win when it comes to the reliability of our code and why we should rewrite basic conditionals to ternaries when can when conditionally assigning variables. And that's on top of being able to remove several lines of code.

Don’t chain ternaries; hard to read

However, as we know with if statements, we can chain on multiple conditions with else if. Say for example, if the user's age was greater than 10, we'd have the greeting "What's up", and if the user was older than 18, we'd say greetings. We can add both of those conditionals as else ifs to our original if statement:

let greeting;
if (age < 10) {
  greeting = "Hey there";
} else if (age > 18) {
  greeting = "Greetings";
} else if (age > 10) {
  greeting = "What's up?";
} else {
  greeting = "That's an interesting age!";
}

What if we wanted to write the same conditions for our ternary? In fact we can, and that's by chaining multiple ternaries together.

This is a bit tricky to setup, so let's walk through this together. For another ternary to be chained on, it is usually as the else condition of the previous ternary. So if for example, the age of a user is 12 (change age variable), the else expression is run of our first ternary, and instead of returning "That's an interesting age", we want to include our next condition, and therefore our next ternary. Is the age greater than 10?

const greeting = age < 10 ? "Hey there" : age > 18 ?

If it is, we return the text "What's up?", otherwise, the else condition of that ternary runs. And then we hit our next condition--is the age greater than 18?

const greeting = age < 10 ? "Hey there" : age > 18 ? "Greetings" : age > 10 ?

If that condition is true, looking back to our if statement, we the greeting text is "Greetings". But in our case, as we mentioned, our provided age was 20, so this condition is false. And the only case we have left is else, and there is no condition for that. So the text for the else case is "That's an interesting age":

const greeting =
  age < 10
    ? "Hey there"
    : age > 18
    ? "Greetings"
    : age > 10
    ? "What's up?"
    : "That's an interesting age";
console.log(greeting);

So just to see that this in fact works, let's provide a value of 12 and see what we get [Run code] And we do in fact get "What's up?".

So what do you think? Do you like ternaries better now? No, this very hard to reason through and write. This highlights an important aspect about ternaries: though you can chain multiple ternary expressions together, you should avoid doing so. If you're thinking this conditional is unreadable as the one who wrote it, its even more unreadable for others. Plus it loses the value of simplicity. So for complex conditionals, use if statements.

This reveals an important concept about the nature of coding in JavaScript is that clarity and readability should be your focus when writing code, not how short you can make it. Sometimes think using tools like the ternary will make our code better, but sometimes it requires writing more code to make it more comprehensible.

Review

So let's review. The basic syntax of the ternary is as follows:

«condition» ? «then expression» : «else expression»;

These three parts, condition, then and else are why this is called a ternary. Note that the word ternary means to have three elements.

It works like this:

  • If condition is truthy, evaluate and return thenExpression.
  • Otherwise, evaluate and return elseExpression.

We also saw that it implicitly returns the value that is created from either the then or else expression. That's what makes it so great for conditionally assigning a value to a variable.

How ternaries help

Ternary expressions allow your code to be not just more simple, but also more predictable. They do this because they cut down on the number of variables that are being reassigned. But note that ternaries shouldn't be used everywhere, say if you need to do multiple things in a conditional such as return a value and perform an action like a console.log.