Letโ€™s take a look at this example code block for error checking a response from a network request. Can we easily determine which errors are returned for which conditional?

const response = await fetch('www.example.com');
if (response.status === HTTP_200_OK) {
  if (response.getContentType() === 'application/json') {
    const data = response.getData();
    if (data.success) {
      return data;
    } else {
      return Error('Data unsuccessful');
    }
  } else {
    return Error('Bad content type');
  }
} else {
  return Error('Response unsuccessful');
}

Itโ€™s not obvious which errors are a result of which if statement due to the complexities introduced by nested conditionals.

How can we improve this? We can flatten the nested conditionals by decoupling the if statements like the following:

const response = await fetch("www.example.com");
if (response.status !== HTTP_200_OK) {
  return Error("Response unsuccessful");
}
if (response.getContentType() !== "application/json") {
  return Error("Bad content type");
}
const data = response.getData();
if (!data.success) {
  return Error("Data unsuccessful");
}
return data;

By refactoring the conditional statements we are able to improve readability and clarify which errors are returned for each specific condition. This coding pattern uses guard clauses as an effective way to guard against invalid conditions to avoid errors.

TLDR

General rules to reduce complexity for nested conditionals:

  1. Avoid nesting beyond two levels; this will greatly improve code readability.
  2. Use guard clauses to effectively flatten nested logic.
  3. Decouple nested logic into separate functions if itโ€™s not easily understandable.

Always think about simplifying code whenever possible to improve readability and maintainability!


๐Ÿ“š Additional Resources

Here are some additional resources to help the understanding of reducing complexity by avoiding nested conditionals: