DEV Community

Discussion on: A New Coding Style for Switch Statements in JavaScript/TypeScript

Collapse
 
avalander profile image
Avalander • Edited

I usually don't use switch statements at all, I prefer a having a dictionary object with a handler function for each case.

const handlers = {
  isBasic: ({ id }) => {
    const entry = getBasicEntry(id)
    console.log(`Processing basic entry "${entry.name}"`)
    doBasicProcessing(entry)
  },
  isCustom: ({ id }) => {
    const entry = getCustomEntry(id)
    console.log(`Processing custom entry "${entry.name}"`)
    doCustomprocessing(entry)
  },
}

const actionHandler = body => {
  const handler = handlers[body.type]
  if (handler == null) throw new Error(`Unknown type ${body.type}`)
  return handler(body)
}

Maybe it's just an idiom I brought from Python, but I think it's more natural to compose functions with this pattern than with switch statements.

Collapse
 
itsjzt profile image
Saurabh Sharma

I also prefer thing method,

Collapse
 
nebrius profile image
Bryan Hughes

I created a little module based on this conversation, and of course gave you a shout-out in the README :D

It's at npmjs.com/package/conditional-reduce

Code looks like this:

console.log(conditionalReduce('dog', {
  dog: () => 'Dogs are great pets',
  cat: () => 'Cat\'s are also great'
})); // Prints "Dogs are great pets"

I realized, thanks to @john_papa 's post below, that this approach also allows us to return a value in the process, so we can inline it in other expressions (or React's JSX)!

Collapse
 
avalander profile image
Avalander • Edited

Wow, that went quick :D

You could also consider having the function conditionalReduce curried and pass the dictionary as the first argument, to make it easier to reuse.

const petReducer = conditionalReduce({
  dog: () => 'Dogs are great pets',
  cat: () => 'Cats are also great'
})

console.log(petReducer('dog')) // 'Dogs are great pets'
console.log(petReducer('cat')) // 'Cats are also great'
Thread Thread
 
nebrius profile image
Bryan Hughes

Also a great idea. I added a new helper so that folks can do either. Thanks again, this makes things cleaner!

const { curry } = require('conditional-reduce');

const dogReducer = curry({
  dog: () => 'Dogs are great pets',
  cat: () => 'Cat\'s are also great'
});

console.log(dogReducer('dog')); // Prints "Dogs are great pets"
console.log(dogReducer('bird')); // Throws 'Invalid conditional value "bird"' exception
const { reduce } = require('conditional-reduce');

console.log(reduce('dog', {
  dog: () => 'Dogs are great pets',
  cat: () => 'Cat\'s are also great'
})); // Prints "Dogs are great pets"

console.log(reduce('bird', {
  dog: () => 'Dogs are great pets',
  cat: () => 'Cat\'s are also great'
})); // Throws 'Invalid conditional value "bird"' exception
Collapse
 
nebrius profile image
Bryan Hughes • Edited

Oh cool, I’ve never seen this approach before! Gonna noodle on this one cause I’ve got a feeling there’s a tiny helper library in here waiting to be built to make the missing handler logic even more elegant and baked in. Thank you for sharing.