JS Refactoring Combo: Replace Nested If-Else with Guards
Tags: vscode, webdev, javascript, typescript
Published: 2021-09-29 16:17:43

**Nested if-else statements can make it unnecessarily complicated to reason about the different executions paths and results of a function**. A loss of productivity and the introduction of bugs due to misunderstandings can be the outcome.

The refactoring "[Replace Nested Conditional with Guard Clauses](https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html)" from Martin Fowler's book "[Refactoring - Improving the Design of Existing Code (2nd Edition)](https://martinfowler.com/articles/refactoring-2nd-ed.html)" can help in those situations.

A **guard clause** checks for a condition and returns from the function if the condition is true, potentially doing some computation and returning a result. It makes it easier to reason about the function by ending one execution path early. 

Here is an example function (from [Replace Nested Conditional with Guard Clauses](https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html), Martin Fowler) before refactoring:

```javascript
function getPayAmount() {
  let result;
  if (isDead)
    result = deadAmount();
  else {
    if (isSeparated)
      result = separatedAmount();
    else {
      if (isRetired)
        result = retiredAmount();
      else
        result = normalPayAmount();
    }
  }
  return result;
}
```

In this example, three nested if-else statements check different conditions (e.g., `isSeparated`) and update a variable `result`. The variable is returned at the end of the function.

The goal is to refactor the function into the following version:
```javascript
function getPayAmount() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retiredAmount();
  return normalPayAmount();
}
```

The refactored function uses guard clauses instead of nested if-else statements. The variable `result` is not necessary anymore and has been removed. The refactored code is easier to understand because there is less state (no variable) and each execution path returns early.

**How can the original function be refactored step-by-step?**

You can simplify the original code by applying two refactorings to each condition:

- **[Inline return](https://p42.ai/documentation/code-assist/inline-return)** converts a variable assignment to a return statement. Such a conversion is possible when the following statement after the assignment in the control flow returns the variable.
- **[Convert if-else to guard clause](https://p42.ai/documentation/code-assist/remove-unnecessary-else)** changes an if-else statement with `return` statements inside into to guard clauses, removing the indentation around the else block.

You can carry out these steps manually or with automation. The [P42 JavaScript Assistant for VS Code](https://marketplace.visualstudio.com/items?itemName=p42ai.refactor) is a refactoring tool that supports both operations. P42 indicates improvement opportunities with blue squiggly underlines. **With refactoring automation, the code can be improved in a matter of seconds**. After a final formatting step, the function has been refactored into the simplified version. 

Here is how refactoring the code looks like in VS Code with P42:

> 💡&nbsp;&nbsp;This blog post is showing P42 JavaScript Assistant v1.29

![Refactor "Replace Nested Conditional with Guard Clauses" Example](https://p42.ai/image/blog/2021-09-29-javascript-refactoring-in-action-replace-nested-if-else-with-guards/refactor-fowler-replace-nested-conditional-with-guard-clauses.gif)

Refactoring is essential for maintaining a healthy codebase, and many small improvements go a long way. By introducing guard clauses, you can often simplify nested if-else statements and make your codebase a little bit better. 

Happy refactoring!