Probably the hottest code refactoring you ever saw 🔥
Tags: functional, javascript, react, tutorial
Published: 2020-01-04 12:38:51

I have some beliefs on programming.

I always re-write, re-think, research, re-invent and refactor.

That did cost me time in the beginning but now, it's not a problem.

Whilst doing that learned how and why things work in JavaScript.

I never settle, even if something works.

Everything matters, function names, variable names, even prop sorting.

I was doing a code review and reached to a function.

I need to mention here that refactoring took me no more than five minutes.

The function was responsible for formatting a given address depending on its country code.

E.g.

```javascript
const address = {
  city: "Belgreen",
  countryCode: 'us',
  county: null,
  state: "Vermont",
  suburb: null,
  zip: "4636"
}
```

The implementation was the following.

```javascript
const addressTextView = () => {
  const city = address.city;
  const state = address.state;
  const zip = address.zip;
  const suburb = address.suburb;
  const county = address.county;
   
  switch (address.countryCode) {
    case 'uk':
      return (
        (zip != null ? zip + ', ' : '') +
        (suburb != null ? suburb + ', ' : '') +
        (city != null ? city + ', ' : '') +
        (state != null ? state : '')
      );
    case 'us':
      return (
        (city != null ? city + ', ' : '') +
        (state != null ? state + ', ' : '') +
        (zip != null ? zip : '')
      );
    case 'nz':
      return (
        (zip != null ? zip + ', ' : '') +
        (city != null ? city + ', ' : '') +
        (county != null ? county + ', ' : '') +
        (state != null ? state : '')
      );
    default:
      return (
        (zip != null ? zip + ', ' : '') +
        (suburb != null ? suburb + ', ' : '') +
        (state != null ? state + ', ' : '') +
        (county != null ? county : '')
      );
  }
}
```

The first thing that bothered me was the ternaries in each case.

Then the repetition.

I started thinking of every return as an array of keys in different order.

I didn't care about null values.

I just started creating patterns.


```javascript
//
  switch (address.countryCode) {
    case 'uk':
      return [zip, suburb, city, state].join(', ');
    case 'us':
      return [city, state, zip].join(', ');
    case 'nz':
      return [zip, city, county, state].join(', ');
    default:
      return [zip, suburb, state, county].join(', ');
//
```

Then, I saw the pattern and I created a function to handle each return.

```javascript
const joinStrings = (...args) => args.join(', ');
```

And the _switch_ looked like this.

```javascript
//
  switch (address.countryCode) {
    case 'uk':
      return joinStrings(zip, suburb, city, state);
    case 'us':
      return joinStrings(city, state, zip);
    case 'nz':
      return joinStrings(zip, city, county, state);
    default:
      return joinStrings(zip, suburb, state, county);
//
```

Then I did something that amazed some people.

The way I filtered out null values from each array. 

```javascript
const joinStrings = (...args) => args.filter(Boolean).join(', ');
```

And final code was this.

```javascript
const joinStrings = (...args) => args.filter(Boolean).join(', ')

const formatAddress = ({ city, county, countryCode, state, suburb, zip }) => { 
  switch (countryCode) {
    case 'uk':
      return joinStrings(zip, suburb, city, state);
    case 'us':
      return joinStrings(city, state, zip);
    case 'nz':
      return joinStrings(zip, city, county, state);
    default:
      return joinStrings(zip, suburb, state, county);
  }
};
```

My thoughts.

Both functions work. Business is happy. 

It's OK to deliver it, but...

always try to improve and never settle if something works.

We had a function called `addressTextView` which was not very clear what it does. It also used the address object from the parent scope.

Then we had a lot of logic with ternaries which where not very clear to read at first either.

I renamed the function to `formatAddress` to be clear and passed the address object as an argument.

I isolated the logic to a different function named `joinStrings`. That function is independent from `formatAddress` and can be reused if necessary.

We also went from 45 lines of code down to 13. 😍

That's it.

I am not bragging, I'm trying to say it doesn't matter if it works but if you want to learn and grow as a developer there are a lot of ways to do that.