clubmate.fi

A good[ish] website

Web development blog, loads of UI and JavaScript topics

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

Filed under: JavaScript— Tagged with: react

Here’s how to get stuff with JavaScript.

This is kind of basic but, boolean logic can handle two values: true and false, or... potato or not potato. Then you can do stuff with it:

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:

Let’s make a helper functions called getSuit that gets us the right icon, which in this case is an SVG wrapped to a React component.

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

<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:

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:

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:

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 keyword flying around. No need to break in the case when returning something.

Nested ternary condition

Nested ternaries work but are cryptic IMO:

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:

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

Object key being the name, in normal fashion. Then access the Object’s properties with the square bracket syntax when you needed:

<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:

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

Conclusions

Maybe you had unconsciously already used that object method, I know I had. Was nice to articulate this in a form of a post. Also, I find myself being really disillusioned about else if.

Comments would go here, but the commenting system isn’t ready yet, sorry. Tweet me @hiljaa if you want to make a correction etc.

  • © 2021 Antti Hiljá
  • About
  • Follow me in Twatter → @hiljaa
  • All rights reserved yadda yadda.
  • I can put just about anything here, no one reads the footer anyways.
  • console.log('Smash the patriarchy!')
  • I love u!