if-if or else-if

Subscribe to my newsletter and never miss my upcoming articles

I often get confused about using multiple if or a chain of if-else if. I finally figured it out.

How to compare

Case 1: Use multiple if statements when you have different things to compare Case 2: Use the if, else-if chain when you have the same thing to compare.

A different way

For case 2, you can substitute the if, else-if chain with a switch-case block. Replacing depends on what you are checking.

For simple mono conditional comparison, it's best to stick with switch case blocks. Here's an example

const getJobDescription = (jobName) => {
  switch(jobName){
    case "painter":
      return "Paints on canvas for art lovers"
    case "developer":
      return "Writes code which runs on machines"
    default:
      return "I'm not sure, I'd google it"
  }
}

For checks with multiple conditions, if-else blocks can do the trick.

const devTitle = (yearsOfWorking, salaryEarned) => {
  if (yearsOfWorking > 5 && salaryEarned > 10000) {
    return "Senior developer"
  } else if (yearsOfWorking > 3 && salaryEarned > 5000){
    return "Intermediate developer"
  } else if (yearsOfWorking < 3 && salaryEarned < 5000){
    return "Junior developer"
  }
  return "Untitled developer"
}

What about nested if statements

When you have 2 levels of nesting, you may not face any issue. But when the nesting gets three levels deep, you may have taken a bad architecture or used an inefficient logic. Let's see an example

const theFactorText = (number) => {
  if (number % 2 !== 0){
    if (number % 5 === 0){
      return "That's the factor"
    } else {
      if (number < 10) {
        return "Not the factor"
      } else {
        throw new Error(
          "Number doesn't fall under any category. Input another"
        )
      }
    }
  }
  return "Not the factor"
}

The code block above shows a function that returns some text based on the number passed in. The if statements are nested and form a messy block. A refactor of the block above would be this

getTheFactor = (number) => {
  if (number % 2 !== 0){
    return number % 5 === 0?
      "That's the factor":
      return number < 10?
        "Not the factor":
        throw new Error("Number doesn't fall under any category. Input another")
  }
  return "Not the factor"
}

The issue with the code above is its readability. A more sensible approach would be to separate the units of functionality into functions like this

const throwErrorIfWrong = (number) => {
  return number < 10?
    "Not the factor":
    throw new Error("Number doesn't fall under any category. Input another")
}
const returnTrueIfMultipleOf5 = (number, cb) => {
  return number % 5 === 0?
    "That's the factor":
    cb()      
}
getTheFactor = (number) => {
  if (number % 2 !== 0) {
    returnTrueIfMultipleOf5(number, throwErrorIfWrong(number))
  }
  return "Not the factor"
}

The code block above shows a more readable function. Just have it mind that you can always break functionality into multiple functions for better readability and testing.

Wrap up

This article goes deeper into the use of conditionals. I recommend you check it out.

Share this article if you found it useful. Thanks for reading ✌🏽🧡

Mark's photo

It's an interesting way. I don't like the ternary operator thing personally, but some good ideas.

What I personally try to do, as a starting point

  • If 'then' returns or throws at the end, there's no need for 'else', it's just code that happens after this early exit.
  • If 'else' returns but 'then' doesn't, invert the condition, then do the above.

Both the flipping and the unwrapping of 'else' can be done by the IDE. This leaves:

const theFactorText = (number) => {
    if (number % 2 === 0) {
        return "Not the factor"
    }
    if (number % 5 === 0) {
        return "That's the factor"
    }
    if (number < 10) {
        return "Not the factor"
    }
    throw new Error(
        "Number doesn't fall under any category. Input another"
    )
}
Osinachi Chukwujama 's photo

This is a clean logical way to go about it

Thanks

Kevin Pliester's photo

If you work a lot with WordPress, it is always better to put the results into variables and then output them at the end, so you can use a filter.

That's why I would do it the same way Mark does. So always a single if, also because it is easier to read for others.

For all who work with PHP and WordPress, something like this could look like this:

/**
 * Here we define the description for the job names and output them.
 *
 * @param string $job_name
 * 
 * @return string
 */
function get_job_description( $job_name ) {

    $job_description = "I'm not sure, I'd google it";

    if ( 'painter' === $job_name ) {
        $job_description = 'Paints on canvas for art lovers';
    }

    if ( 'developer' === $job_name ) {
        $job_description = 'Writes code which runs on machines';
    }

    return apply_filters( 'job_description', $job_description, $job_name );
}

/**
 * Now other users can use WordPress for their projects, change or extend the description.
 * 
 * @param string $job_description
 * @param string $job_name
 *
 * @return string
 */ 
add_filter( 'job_description', function( $job_description, $job_name ) {

    if ( 'gamer' === $job_name ) {
        $job_description = 'Is a gamer and plays on pc master race';
    }

    return $job_description;
}, 10, 2 );

Well, I always try to build in a way that others with hooks can rework the function and read it at any time. Hence the individual IF blocks.

Osinachi Chukwujama 's photo

Ah, reassignment

Also works

One question: Where did you define the apply_filters function?

Kevin Pliester's photo

Osinachi Chukwujama

Nowhere. So I wrote that you have to use WordPress. The filter or hook is from WordPress. I just wanted to contribute something from the WordPress corner, simply because so few people write about WordPress and PHP here :D

Your post is amazing and thank you for your comment!