There is more than one way to make your code readable
Tags: codenewbie
Published: 2020-06-15 16:53:37

Let's say you find the following code: 
```typescript
  useEffect(() => {
    const generateId = (acc: number, curr: string) => 
      acc += cur.charCodeAt(0)

    if (id === 0) {
      let x = profileId.split('').reduce(generateId, 0)
      setId(x % 8 + 1)
    }
    
  },[profileId])
```

What do we know about this effect? 
1. It runs when the profileId changes and if some other id is equal to zero. 
2. The profileId is converted from a string to a string array.
3. The string array is reduced using a generateId function that returns `(acc += cur.charCodeAt(0)) % 8 + 1`, _whatever that is_.

If a less experienced developer finds this in a React component, they may be confronted with a few obstacles:
1. How comfortable are they with `.reduce()`? What are _acc_ and _cum_? 
2. What is _x_, and why are we setting the other ID to whatever _x_ is?
3. What is the intent of the effect? Why is it needed?

A more experienced developer, perhaps even the developer who wrote this code, will face similar obstacles. How can we write this code so that someone can understand what is going on right away? Here are a few attempts.

## Comment your code, and use variable names that reveal their intent

Variable are _things_, and we should name those things well! Call them what they are! It's not an ID, it's an Avatar ID. This would be an improvement even without the comment block. I prefer to think of `.reduce()` as having state, explained beautifully by Joel in under 5 minutes:

{% link https://dev.to/joelnet/minute-javascript-array-s-reduce-method-18h0 %}

An informative comment or comment block causes no penalty to performance, and you won't lose cool points for writing one. I promise the developer reading your code would rather understand what is going on than being impressed by your one-line function.

If you are fortunate enough to be mentoring junior developers with some frequency, there is also no penalty for leveraging the community for the bits of the JavaScript developers don't touch every day.

```typescript
  /**
   * Generate the avatar id
   * 
   * 1. convert licensingProfileId from string into string array
   * 2. (reducer) sum the ascii code for each character
   * 3. (reducer) mod by 8 for the 8 possible avatars
   * 4. (reducer) add 1 to generate the possible id
   *
   * Learn more about .reduce():
   * MDN: (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
   * Minute JavaScript: (https://dev.to/joelnet/minute-javascript-array-s-reduce-method-18h0)
   * 
   * .charCodeAt(0) returns the ascii code of a string character at the index passed in. 
   * In this case, item is always a single-character string.
   */
  useEffect(() => {
    const generateAvatarId = (state: number, item: string) => 
      state += item.charCodeAt(0)

    if (avatarId === 0) {
      let avatarId = licensingProfileId.split('').reduce(generateAvatarId, 0)
      setAvatarId(avatarId % 8 + 1)
    }
    
  },[licensingProfileId])
```

## Shorter code isn't necessarily more readable

Remember when your math teacher would hand your assignments back covered in red ink with _Show your work!!_ written across the top? Just me? Feel free to follow this strategy here as well. I personally wouldn't go as far as this example with transient/placeholder variables at each step.

```typescript
  /**
   * Generate the avatar id
   */
  useEffect(() => {
    const generateAvatarId = (state: number, item: string) => {
      let asciiCode = item.charCodeAt(0) // Get a number from the string character
      state += asciiCode // state is the sum of the ascii codes
      return state
    }

    if (avatarId === 0) {
      // transform string to array so that we can use .reduce()
      let stringArray = licensingProfileId.split('') 
      // starting from 0, sum the ascii codes for each character in the profileId
      let asciiCodeSum = stringArray.reduce(generateAvatarId, 0)
      // There are only 8 avatars to choose from
      let selectedAvatar = asciiCodeSum % 8
      // Add 1 to assign an ID of 1–8
      let selectedAvatarId = selectedAvatar + 1
      setAvatarId(selectedAvatarId)
    }
    
  },[licensingProfileId])
```

Whatever combination of techniques you decide to use, the result will save questions and head scratching when the code has been stale for a while.