If… Else, or not!

Fredrik Jensen
DailyJS
Published in
5 min readJun 15, 2018

Maybe one of the most classical features of programming is conditionals. But after I started avoiding it, I have found myself writing much more cleaner and reasonable code.

It was when I started to get serious with React, that I realized that my own code had too much of If… Else statements. I did refactor with the goal of removing much of it. And the result was much more readable and reasonable code. I have actually become a bit fanatic about it, I think a lot of conditionals is a sign that your codebase is not healthy.

This is more or less my process when I see a lot of conditionals during code reviews:

  • Are this function actually doing different things, and should be split out to different functions instead?
  • Is it absolutely necessary to check for this conditional in this function or should the responsibility be somewhere else?
  • Can it be done in a more readable way? There is different patterns that can replace conditionals, one of my favorites is a pattern called ObjectMapping.
  • If we have to use a conditional. I would remove the Elses, and only keep the ifs and a default case.

So let’s dive into some alternatives techniques for dealing with different kind of conditionals.

Remove Elses

This is a quite easy trick, but it is effective:

if (red) {
return true;
} else if (blue) {
return true;
} else {
return false;
}

Refactored into this:

if (red || blue) {
return true;
}
return false;

There are several reasons that I prefer the second one. First of all, it has a default case and it is more clear that the if statements are not normal conditions. It is doing exactly the same, but it reads better. The fact that it is short is nice, but is not the goal. Readability always wins.

Composition

If you figure that your functions actually is doing different things, composition is a great pattern that can be used. You split out your functions into smaller, more specific functions and compose them together. This way you can make yourself a set of utility functions you can use in different part of the application.

Let us say we write a function to get only female animals with fur that have claws (it makes total sense 😀). It could look something like this:

import { flow } from 'lodash';const femaleAnimalsWithFurAndClaws = flow(
getFemales,
getAnimalsWithFur,
getAnimalsWithClaws,
)(animals);

It is quite easy to see how we could reuse a function like getFemales.
I wrote a bit about this pattern in an earlier article.

The ObjectMapper

This is actually one of my favorite patterns. It can actually be applied to a lot of different situations, both in backend and frontend programming. The great thing is that the pattern is really simple and readable. When I use it, I feel that my code turns into specifications rather than code. Which I think is really great, because it get’s so easy to see what is going on.

Let me try do demonstrate the basic of the pattern:

const colors = {
red: true,
blue: true,
'default': false,
};
const colorMapper = color => colors[color] || colors['default'];const color = colorMapper(item.color);

It works like this:
1. An object specifying the results
2. A mapping function

It is quite nice to have the default case. Because if we call the mapping functions without an argument, or if we get unexpected input, the function still work. If we call it with a new color: colorMapper(‘green’), we will just get the default false case. But we can easily add new cases later on.

We probably could have used a switch statement here and gained more or less the same result. But personally I am not that big fan of the syntax of it, and it for me it just seems kind of purer and more elegant to use a regular object and a mapper function.

ObjectMapping and React

When working with React, this pattern rally shines. Let us say we want to render out an array to different components. Instead of having a lot of conditionals in our code, we can simple use the ObjectMapper pattern. So, our data look like this; Every object has a type and content key. The value of the content key can be different on each item, that is totally fine.

const items = [{
type: ‘hero’,
content: : {…},
}, {
type: 'text',
content: : {…},
}, {
type: 'image_and_text',
content: : {…},
}, {
type: 'text',
content: : {…},
}, {
type: 'call_to_action',
content: : {…},
}];

We write a mapper functions, and for each key we return the specific component. All of or components, only take on prop, which is content.

const components = {
hero: HeroComponent,
text: TextComponent,
image_and_text: ImageAndTextComponent,
call_to_action: CallToActionComponent,
'default': null,
};
const componentMapper = type =>
components[type] || components['default'];

And then we can use it like this in our React application:

import react from ‘react’;const RenderItems = props => {

const componentList = props.items((item, index) => {
const Component = componentMapper(item.type);
return <Component content={item.content} />
};
return (
<div>
{componentList}
</div>
)
};

A bonus here is that if our content come from an external source (like a CMS), and someone adds a new module. It will just render out null, and nothing will break. And we can just add a new components to our mapping object later on.

There is probably a lot more of different patterns and methods that can use to fight the Ifs and Elses in your code. But this is just a couple of methods that I have found the most useful. Keep up the fight 💪

--

--