Why You Need To Stop Using Nested If Statements

Typical use case for nested ifs: Validating data…
Don’t do this! 👇

There’s a better way:

See how much cleaner it is? Instead of nesting ifs, we have multiple if statements that do a check and return
immediately if the condition wasn't met.
In this pattern, we can call each of the if
statements a guard clause.
If you do a lot of Node.js, you’ve probably seen this flow in Express middleware:

It’s much better than this, right? :

You never go beyond one level of nesting. We can avoid the mess that we see in callback hell.
How to convert nested ifs to guard clauses
The logic for this for doing this is simple:
1. Find the innermost/success if
Here we can clearly see it’s the cond3
if. After this, if
we don't do any more checks and take the action we've always wanted to take.

2. Invert the outermost if and return
Negate the if
condition to put the else
statements' body in there and add a return
after.
Delete the else
braces (keep the body, it still contains the formerly nested if
s, and move the closing if
brace to just after the return
.
So:

3. Do the same for each nested if until you reach the success if
And then:

And finally:

I use the JavaScript Booster extension to make inverting if statements in VS Code much easier.

Check out this article for an awesome list of VSCode extensions you should definitely install alongside with JavaScript Booster.
Tip: Split guard clauses into multiple functions and always avoid if/else
What if we want to do something other after checking the data in an if/else
? For instance:

In this function regardless of cond1
's value, the 'after cond1 check'
the line will still print. Similar thing for the cond2
value if cond1
is true
.
In this case, it takes a bit more work to use guard clauses:
If we try to use guard clauses, we’ll end up repeating the lines that come after the if/else
checks:

Because the lines must be printed, we print them in the guard clause before returning. And then, we print it in all(!) the following guard clauses. And once again, in the main function body if all the guard clauses were passed.
So what can we do about this? How can we use guard clauses and still stick to the DRY principle?
Well, we split the logic into multiple functions:

Let’s apply this to the Express middleware we saw earlier:

In a way, we’ve replaced the if/else
statements with a chain of responsibility pattern. Of course, this might be an overkill for simple logic like a basic Express request middleware, but the advantage here is that it delegates each additional check to a separate function, separating responsibilities and preventing excess nesting.
Key takeaways
Using nested ifs in code often leads to complex and hard-to-maintain code; Instead, we can use guard clauses to make our code more readable and linear.
We can apply guard clauses to different scenarios and split them into multiple functions to avoid repetition and split responsibilities. By adopting this pattern, we end up writing cleaner and more maintainable code.
Every Crazy Thing JavaScript Does
Just when you thought you knew all the quirks. Avoid painful bugs and save valuable time with Every Crazy Thing JavaScript Does, a captivating guide to the subtle caveats and lesser-known parts of JavaScript.
Get a free copy here today.

In Plain English 🚀
Thank you for being a part of the In Plain English community! Before you go:
- Be sure to clap and follow the writer ️👏️️
- Follow us: X | LinkedIn | YouTube | Discord | Newsletter
- Visit our other platforms: Stackademic | CoFeed | Venture | Cubed
- More content at PlainEnglish.io