# Doing more complex conditional logic, getting more than two different values

Here’s how to get stuff with JavaScript.

This is basic, but Boolean logic can handle two values: `true` and `false`,
or... potato or _not_ potato. Then you can do stuff with it:

```js {5}
import DefaultIcon from './icons/Default'
import SpecialIcon from './icons/Special'

const hasDefaultIcon = true
const Icon = hasDefaultIcon ? DefaultIcon : SpecialIcon
```

But what if **the value can be more than two things?** This post is about that.

## The demo code

Let’s say we get an array from an API: `['club', 'diamond', 'heart', 'spade']`,
and our task is to render playing cards, like so:

[Interactive example](/getting-values-in-javascript)

Let’s make a helper function called `getSuit` that gets us the right icon, which
in this case is
[an SVG wrapped to a React component](/getting-values-in-javascript).

The above cards were rendered by the following code (getter highlighted):

```jsx {3}
<CardWrap>
  {suits.map(suit => {
    const Icon = getSuit(suit)

    return (
      <PlayingCard>
        <Icon width={30} />
      </PlayingCard>
    )
  })}
</CardWrap>
```

## Loads of if else statements

One way of implementing the icon getter helper is with a chain of `if else`
conditions:

```js
const getSuit = suit => {
  if (suit === 'club') {
    return ClubsIcon
  } else if (suit === 'diamond') {
    return DiamondsIcon
  } else if (suit === 'heart') {
    return HeartsIcon
  } else if (suit === 'spade') {
    return SpadesIcon
  } else {
    return null
  }
}
```

That mess just doesn’t spark joy. I’ve completely stopped using the `if else`.

## Loads of if statements

Somehow I find these `if` statements extremely simple and super readable:

```js
const getSuit = suit => {
  if (suit === 'club') return ClubsIcon
  if (suit === 'diamond') return DiamondsIcon
  if (suit === 'heart') return HeartsIcon
  if (suit === 'spade') return SpadesIcon

  return null
}
```

There’s very little guesswork on how that works.

## The switch case

Switch cases were basically made for this:

```js
const getSuit = suit => {
  switch (suit) {
    case 'club':
      return ClubsIcon
    case 'diamond':
      return DiamondsIcon
    case 'heart':
      return HeartsIcon
    case 'spade':
      return SpadesIcon
    default:
      return null
  }
}
```

Loads of keywords are flying around. There is no need for `break` in a `case`
when returning something.

## Nested ternary condition

Nested ternaries work but are cryptic IMO:

```jsx
const getSuit = suit => {
  return suit === 'club'
    ? ClubsIcon
    : suit === 'diamond'
      ? DiamondsIcon
      : suit === 'heart'
        ? HeartsIcon
        : suit === 'spade'
          ? SpadesIcon
          : null
}
```

## Just an Object

Probably my favorite method of getting values is to just store them into an
object, like so:

```js
const suiteIcons = {
  club: ClubsIcon,
  diamond: DiamondsIcon,
  heart: HeartsIcon,
  spade: SpadesIcon,
}
```

The object key is the name, as usual. Then access the object’s properties with
bracket notation when you need them:

```jsx {3}
<CardWrap>
  {suits.map(suit => {
    const Icon = suiteIcons[suit] || null

    return (
      <PlayingCard>
        <Icon width={30} />
      </PlayingCard>
    )
  })}
</CardWrap>
```

**Note about the fallback**: `suiteIcons.potato` is `undefined`, not `null`, and
React will crash if it’s not handled.

You can also do shenanigans like this, bake it all into one thing:

```js
const Icon =
  {
    club: ClubsIcon,
    diamond: DiamondsIcon,
    heart: HeartsIcon,
    spade: SpadesIcon,
  }[suit] || null
```

## Conclusions

Maybe you had already used that object method without realizing it. I know I
had. It was nice to articulate this in a post. I also find myself becoming
disillusioned about `else if`.
