How to Write Conditional Statements like a Pro ๐
Tips on writing cleaner conditional statements (if else)
As a software engineer, I use conditional statements frequently. In this post, I will share with you how to write a better conditional statement. I hope that this approach will help you to write cleaner code so that your teammates will love your code. Here are the tips.
Use Guards
Let's take a look at the example below
if (user.isActive) {
// do some process for active user
}
return false
Imagine that the processing inside the if
block is multiple lines of code. The longer the line of code, the harder to read. We can change the code and make the if statement a guard. See the example below
if (!user.isActive) {
return false
}
// do some processing
As you can see in the example above, we change the condition on the if
statement and it will return fast. So the if
statement becomes a guard. It returns fast and guards the rest of the code not to be executed. Furthermore, there is only a single line of code within the if
block. This makes it easier to read & understand.
Guard on If Else
How about an if else
statement? Let's see the example
if (user.isActive) {
// do some processing
} else {
throw new Error('inactive_user')
}
We can still use guard on this. See the refactored code below
if (!user.isActive) {
throw new Error('inactive_user')
}
// do some processing
With this technique, we don't even need to write an else
statement anymore. The guard will throw an error fast and protect the rest of the code.
What if both the if
block and the else
block have multiple lines of code? Hold on, I will explain it. Just continue reading ๐. You can read decompose conditional statement section.
Guard on Loop
You can also use conditional statements as a guard inside a loop. The concept is that the guard is able to break
or continue
fast. If you want to break
or continue
inside the loop, you can put it at the beginning of the loop.
const products = [
{id: 1, isActive: 1 },
{id: 2, isActive: 0 },
{id: 3, isActive: 1 },
]
for (const product of products) {
if(!product.isActive) continue // this is a guard
// do something
}
const carts = [
{id: 1, isActive: 1 },
{id: 2, isActive: 0 },
{id: 3, isActive: 1 },
]
for (const cartItem of carts) {
if(!cartItem.isActive) break // this is a guard
// do something
}
Decompose Conditional Statement
If you have a long conditional statement, try to decompose it. Look at the example.
function processToFinalExam(student) {
if (
student.attendanceCount >= 10 &&
student.projects.length === 4 &&
student.finalProjectStatus === 'submitted'
) {
console.log('calculate attendance percentage')
console.log('calculate average exam score')
console.log('calculate average project score')
console.log('calculate final project score')
console.log('calculate total score')
console.log('check if student is allowed to attend the exam')
} else {
console.log('check if student is eligible for chapter remedial')
console.log('notify parent via push notification')
console.log('generate warning letter')
}
}
In the example, I have a long conditional statement. Imagine a school that wants to check whether a student can attend the exam or not. If the student meets the minimum criteria, then calculate the total score and check eligibility to attend the exam.
In the if
and else
block, I put some console.log
as a replacement for some example processes to make it simple. Now the question is, how to make the conditional statement cleaner and more readable? Ok, let's decompose the statement by extracting the statements into functions.
Extract Function
First, let's extract the statements on if
block.
function processToFinalExam(student) {
if (
student.attendanceCount >= 10 &&
student.projects.length === 4 &&
student.finalProjectStatus === 'submitted'
) {
checkExamEligibility()
} else {
console.log('check if student is eligible for remedial class')
console.log('notify parent via push notification')
console.log('generate warning letter')
}
}
function checkExamEligibility () {
console.log('calculate attendance percentage')
console.log('calculate average exam score')
console.log('calculate average project score')
console.log('calculate final project score')
console.log('calculate total score')
console.log('check if student is allowed to attend the exam')
}
I move the code from the if
block to a new function called checkExamEligibility
. This is just an example function. I don't use any parameters for simplicity. I hope that you got the idea.
Next, extract the code inside the else
block into function.
function processToFinalExam(student) {
if (
student.attendanceCount >= 10 &&
student.projects.length === 4 &&
student.finalProjectStatus === 'submitted'
) {
checkExamEligibility()
} else {
checkRemedialEligibility()
}
}
function checkExamEligibility () {
console.log('calculate attendance percentage')
console.log('calculate average exam score')
console.log('calculate average project score')
console.log('calculate final project score')
console.log('calculate total score')
console.log('check if student is allowed to attend the exam')
}
function checkRemedialEligibility () {
console.log('check if student is eligible for remedial class')
console.log('notify parent via push notification')
console.log('generate warning letter')
}
After extracting statements into functions, the overall conditional statement is more readable now. But, you can actually refactor once more.
Extract Condition / Control Structure into Function
Let's extract the condition into a new function.
function processToFinalExam(student) {
if (isQualified(student)) {
checkExamEligibility()
} else {
checkRemedialEligibility()
}
}
function isQualified (student) {
return student.attendanceCount >= 10 &&
student.projects.length === 4 &&
student.finalProjectStatus === 'submitted'
}
function checkExamEligibility () {
console.log('calculate attendance percentage')
console.log('calculate average exam score')
console.log('calculate average project score')
console.log('calculate final project score')
console.log('calculate total score')
console.log('check if student is allowed to attend the exam')
}
function checkRemedialEligibility () {
console.log('check if student is eligible for remedial class')
console.log('notify parent via push notification')
console.log('generate warning letter')
}
You can also add constant for a better readability.
const MIN_ATTENDANCE_COUNT = 10
const MIN_PROJECT_COUNT = 4
const FINAL_PROJECT_STATUS = {
SUBMITTED: 'submitted'
}
function isQualified (student) {
return student.attendanceCount >= MIN_ATTENDANCE_COUNT &&
student.projects.length === MIN_PROJECT_COUNT &&
student.finalProjectStatus === FINAL_PROJECT_STATUS.SUBMITTED
}
Next, you can remove the else
on processToFinalExam
function.
function processToFinalExam(student) {
if (isQualified(student)) {
checkExamEligibility()
return
}
checkRemedialEligibility()
}
Now, the function become shorter and easy to understand.
Summary
In this article, I shared about two ways of refactoring your If else
statement by using Guard and Decompose Conditional Statements. A guard can be used to return
, fail
, break
, or continue
fast, so you can protect the rest of the code to be executed. Decompose conditional statement can be used by extracting the condition/control structure, and the code on if
and else
block into new functions. There are many other techniques to make your conditional statement cleaner, If you want to know more about it, please leave a comment below.
The benefits of applying Guard and Decompose Conditional Statement are:
You can avoid a long function, and create shorter functions that focus on a specific task. This is good for the long term.
Make your code cleaner & more readable
I hope that this article can help you learn how to write a better and cleaner if
else
statement.