Avoid Nested Conditions with Early Return

Avoid Nested Conditions with Early Return


Consider the following example in JavaScript:

function validateOrder(order) {
  if (order) {
    if (order.items && order.items.length > 0) {
      if (!order.canceled) {
        if (order.user && order.user.active) {
          console.log("Order is valid and ready to be processed.");
        } else {
          console.log("Inactive user.");
        }
      } else {
        console.log("Order canceled.");
      }
    } else {
      console.log("Order has no items.");
    }
  } else {
    console.log("Invalid order.");
  }
}

This code is deeply nested and hard to read. The main logic is buried inside several conditional blocks. As this function grows, it becomes harder to maintain, harder to test, and easier to break.

A simple approach to handle this situation is to apply early return conditions. This way, you avoid nested conditions, reduce cognitive overhead, and exit the function early if a required condition is not met.

function validateOrder(order) {
  if (!order) {
    console.log("Invalid order.");
    return;
  }

  if (!order.items || order.items.length === 0) {
    console.log("Order has no items.");
    return;
  }

  if (order.canceled) {
    console.log("Order canceled.");
    return;
  }

  if (!order.user || !order.user.active) {
    console.log("Inactive user.");
    return;
  }

  console.log("Order is valid and ready to be processed.");
}

Using early returns makes the function flat, readable, and easier to maintain. Each failure condition is handled immediately, avoiding unnecessary else blocks and reducing indentation.

Watch Out for Too Many Returns

If a function starts accumulating too many return statements, it might be doing too much. In these cases, consider breaking it into smaller, focused functions, each responsible for a single concern. For example:

function isOrderValid(order) {
  return order && order.items?.length > 0 && !order.canceled;
}

function isUserValid(user) {
  return user && user.active;
}

function validateOrder(order) {
  if(isOrderValid(order) && isUserValid(order.user)) {
    console.log("Order is valid and ready to be processed.");
  }
}