DEV Community

Washing your code: avoid conditions

Artem Sapegin on July 15, 2019

You’re reading an excerpt of my upcoming book on clean code, “Washing your code: write once, read seven times.” Preorder it on Leanpub or read a ...
Collapse
 
vitalets profile image
Vitaliy Potapov

Great article! I use all the same principles in code.
2 more case I'd like to mention:

1.Often we need to check some condition and throw error. E.g.:

function f(foo) {
  if (foo > 0) {
      throw new Error('foo should be greater than zero!');
  }
  // ...
}

To remove such boilerplate I use throw-utils library:

const {throwIf} = require('throw-utils');

function f(foo) {
  throwIf(foo > 0, 'foo should be greater than zero!');
  // ...
}

2.When we need to return value from function or throw an error:

function f() {
  // ... calc the result
  if (!result) {
    throw new Error('MyError');
  }
  return result;
}

It can be also simplified with throwError utility method:

const {throwError} = require('throw-utils');

function f() {
  // ... calc the result
  return result || throwError('MyError');
}
Collapse
 
falco467 profile image
falco467

In "deduplicating" I would even coerce it to a single line:

counts[url] = (counts[url]||0) + votes

Collapse
 
qm3ster profile image
Mihail Malo

I can never get over the shame of (products || []).map(.
Who knows what other things I will be doing with the resulting empty array afterwards?!
I always break out to imperative to do a

if (!Array.isArray(products)) return
const x = products.map(
Collapse
 
falco467 profile image
falco467

I would find the whole horns&hooves stuff a lot more readable with ternary operators instead of this function array construct.

const getSpecialOffersArray = withSessionCache(
  SPECIAL_OFFERS_CACHE_KEY,
  brand =>
    ({
      [BRANDS.HORNS_AND_HOOVES]: getHornsAndHoovesSpecialOffers,
      [BRANDS.PAWS_AND_TAILS]: getPawsAndTailsSpecialOffers
    }[brand]())
);

I would instead write as:

const getSOArray = wrapFnWithCache(SPECIAL_OFFERS_KEY, 
    brand === BRANDS.HnH ? getHnHSpecialOffers 
  : brand === BRANDS.PnT ? getPnTSpecialOffers
  : null)
Collapse
 
dexterstpierre profile image
Dexter St-Pierre

Although I agree that the original example wasn't the most readable, I don't think that your example would scale very well. If you moved the declaration of the object out of the function (possibly to a different file) and access the value the way that Artem did I think you would have a much more readable function. But that's just my opinion :)

Collapse
 
acostalima profile image
André Costa Lima

Excellent article! 👏