Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed

Viewed 1146

On Sonarqube I'm getting this as critical issue, can somebody help me in this to sort out this issue. Here is the code details, please let me know how can I refactor this code with switch case :

const getEmailTo = (subject) => {

  switch (subject) {
    case 'POWERUP_REWARDS':
        return COMMON_EMAIL;
    case 'GAME_INFORMER':
        return COMMON_EMAIL;
    case 'ONLINE_ORDER':
        return 'test@gmail.com';
    case 'STORE_EXPERIENCE':
        return 'test@gmail.com';
    case 'APP_REVIEW':
        return COMMON_EMAIL;
    case 'SOMETHING_ELSE':
        return COMMON_EMAIL;
    default:
        return '';
  }
};
3 Answers

Make your code a bit more DRY and simplified by collecting your common cases that return the same values. I don't think SonarQube validates readability, but proper use of whitespace can go a long way in readability of unfamiliar code. It's opinionated, but I like a line between case returns.

const getEmailTo = (subject) => {
  switch (subject) {
    case 'POWERUP_REWARDS':
    case 'GAME_INFORMER':
    case 'APP_REVIEW':
    case 'SOMETHING_ELSE':
        return COMMON_EMAIL;

    case 'ONLINE_ORDER':
    case 'STORE_EXPERIENCE':
        return 'test@gmail.com';

    default:
        return '';
  }
};

You can use an object to map subjects to email addresses and return the email address corresponding to the subject.

const TEST_EMAIL = 'test@gmail.com'

const emails = {
  POWERUP_REWARDS: COMMON_EMAIL,
  GAME_INFORMER: COMMON_EMAIL,
  APP_REVIEW: COMMON_EMAIL,
  SOMETHING_ELSE: COMMON_EMAIL,
  ONLINE_ORDER: TEST_EMAIL,
  STORE_EXPERIENCE: TEST_EMAIL,
}

const getEmailTo = (subject) => emails[subject] || ''

I'm not sure if returning '' is fine when a subject is not in the mapping. I would suggest throwing an error to let the caller know the subject is invalid.

const getEmailTo = (subject) => {
  if (!(subject in emails)) {
    throw new Error(`Invalid subject: ${subject}`)
  }

  return emails[subject]
}

You can just put the related case statements next to each other, like this:

const getEmailTo = (subject) => {
   switch (subject) {
       case 'POWERUP_REWARDS':
       case 'GAME_INFORMER':
       case 'APP_REVIEW':
       case 'SOMETHING_ELSE':
         return COMMON_EMAIL;
       case 'ONLINE_ORDER':
       case 'STORE_EXPERIENCE':
         return 'test@gmail.com';
       default:
         return '';
   }
};
Related