Flat is better than nested
Tags: programming, beginners
Published: 2021-01-27 09:20:44

---
title: Flat is better than nested
tags:
 - programming
 - beginners
published: true
---
Nesting code is a common feature in a programming language. While it has some advantages, it is mainly considered an anti-pattern. There are a number of problems when nesting code:

- The code is hard to read
- The context is hard to understand
- Hard to maintain, whilst developers will try to avoid it

Let's explore different ways to invert nested conditions and make code easier to work with.

## Executing functions

### Inverting conditions

Consider the following example code:

```
function payBill(user = { isLoggedIn: false }, amount = 0) {
  if (user) {
    if (user.isLoggedIn) {
      if (amount > 0) {
        // pay the bill
      } else {
        throw new Error("Invalid amount");
      }
    } else {
      throw new Error("User needs to login");
    }
  } else {
    throw new Error("User doesnt exist");
  }
}
```

This code has a nesting depth of 3 and this will probably continue if we need to cover different validation scenarios. Simply by inverting the conditions we can reduce the nesting depth to 1 as follows:

```
function payBill(user = { isLoggedIn: false }, amount = 0) {
  if (!user) {
    throw new Error("User doesnt exist");
  }

  if (!user.isLoggedIn) {
    throw new Error("User needs to login");
  }

  if (amount <= 0) {
    throw new Error("Invalid amount");
  }

  // Pay bill
}
```

This code will work exactly the same way as the first example. The only difference is that it is easier to read, understand and maintain.

### Early return

This is another solution that can be used in function as a guard clause before executing the function.

For example, instead of wrapping everything in a condition like this:

```
function doSomething(myParam) {
  if(myParam){
    // Do something here
  }
}
```

You can simply revert the condition and stop the execution of the function when the condition is not met.

```
function doSomething(myParam) {
  if(!myParam){
    return;
  }

  // Do something here
}
```

## Loops
Building custom logic within loops is something common that we all do. We can definitely improve the way we execute loops by reducing the nested conditioning.

Here is an example with nested conditions:
```
const myList = ["one", "two", null, "four", "", "six"];
for (let i = 0; i < myList.length; i++) {
  const item = myList[i];
  if (item !== null) {
    if (item !== "") {
      // Do something with current item
      console.log(item);
    }
  }
}
```

Here is an improved version:
```
const myList = ["one", "two", null, "four", "", "six"];
for (let i = 0; i < myList.length; i++) {
  const item = myList[i];
  if (item === null) {
    continue;
  }

  if (item === "") {
    continue;
  }

  // Do something with current item
  console.log(item);
}
```
By using the `continue` statement, the loop stops the current iteration of the loop and continues with the next iteration. This stops the nested conditions and makes the flow more linear, either stopping the iteration to go further down the block or continue with the next item.

The same can be done with `.forEach` loop. 
```
const myList = ["one", "two", null, "four", "", "six"];
myList.forEach((item) => {
  if (item === null) {
    return;
  }

  if (item === "") {
    return;
  }

  // Do something with current item
  console.log(item);
});
```
The `return` statement plays the same role as `continue` statement in `for` loop. 

# Conclusion
Minimizing nesting and applying these simple tricks can make your life much easier. It's not only going to make the code more readable and understandable, but it will also improve your coding style. Your teammates will thank you for that later.