DEV Community

Cover image for Switch statements in javascript – How to refactor?
Ajay Kumar Verma
Ajay Kumar Verma

Posted on • Updated on • Originally published at weekendtutorial.com

Switch statements in javascript – How to refactor?

The Switch statements are perfectly nice and majorly used in the other traditional language like C, C++, and Java.

Why Switch statement?

The switch statement executes different actions based on the different conditions. Of course, we can solve the above with an if-else ladder but that will make the program too much clumsy. Also, the if-else ladder is advisable only if you have a max of 3 conditions to check.

Javascript has the switch statement but if you’re interested in python then just as a side information python doesn’t have the switch statement but it achieves the same with the dictionary mapping.

Since the dictionary mapping is similar to object creation in javascript, taking the inspiration from python, we can replace the switch statement with multiple objects which is not a bad idea. This will keep the code simple and maintainable in long run.

Let’s see the most occurred examples which we must have faced in our coding career -


Example 1

Write a code that returns the todays’ day in string e.g Sunday

using the switch statement

let day = new Date().getDay(); 
switch (day) {
  case 0:
    day = "Sunday";
    break;
  case 1:
    day = "Monday";
    break;
  case 2:
     day = "Tuesday";
    break;
  case 3:
    day = "Wednesday";
    break;
  case 4:
    day = "Thursday";
    break;
  case 5:
    day = "Friday";
    break;
  case 6:
    day = "Saturday";
}
console.log(day); // for 30/01/2022 it will return Sunday
Enter fullscreen mode Exit fullscreen mode

Output verification from console.log

using Switch

without switch i.e Refactored code

const day = new Date().getDay();
const dayMapper = {
    0: "Sunday",
    1: "Monday",
    2: "Tuesday",
    3: "Wednesday",
    4: "Thursday",
    5: "Friday",
    6: "Saturday"
};
if (dayMapper.hasOwnProperty(day)) {
  console.log(dayMapper[day]); // Sunday
} else {
  console.log("Something went wrong");
}
Enter fullscreen mode Exit fullscreen mode

Output verification from console.log

without Switch

This is the most basic example, lets's see one more common but complex example

UseCase: Suppose we have to send a GA event for a page e.g for the Home page we will be sending the event label as Page name + its current layout name.

The catch is the page name is coming from the data attribute in DOM.

Let me explain it further with an example -

we need to return the (Page name_Layout name) following for the page name found in the data attribute

homePage -> Home_index
productPage -> Product_pdp
blogPage -> Blog_blog
Enter fullscreen mode Exit fullscreen mode

Example 2

Assume HTML which has the page name stored in data attribute is written as -

HTML for homepage:
<div id="my-div" data-page-name="homepage"></div>
Enter fullscreen mode Exit fullscreen mode

using the switch statement

let pageName = document.querySelector('#my-div').dataset.pageName;
let page;
let layout;
let ans;
switch (pageName) {
  case "homepage":
    page = "Home";
    layout = "index";
    break;
  case "productpage":
    page = "Product";
    layout = "pdp";
    break;
  case "blogpage":
    page = "Blog";
    layout = "blog";
    break;
}
ans = page + '_' + layout;
console.log(ans);
Enter fullscreen mode Exit fullscreen mode

Output verification from console.log

page mapper using switch

without switch i.e Refactored code

let pageName = document.querySelector('#my-div').dataset.pageName;
let dataPageMapper = {
  homepage: 'Home',
  productpage: 'Product',
  blogpage: 'Blog' 
};
let pageLayoutMapper = {
  home: 'index',
  product: 'pdp',
  blog: 'blog' 
};
let page = dataPageMapper.hasOwnProperty(pageName) && dataPageMapper[pageName];
let layout = pageLayoutMapper[page.toLowerCase()];
let ans = page + '_' + layout;
console.log(ans);
Enter fullscreen mode Exit fullscreen mode

Output verification from console.log

page mapper with no switch

Conclusion

Above one is the cleaner way to do it. If in the future, we have more pages available we just need to make the entries in the mapper objects, that's it.

But with a switch statement, it will be a long ladder of statements and if you forgot to add the break statement then you will fall into the famous switch pitfalls.

Let me know your thoughts like how you handle the switch thing in your code.

If you like my article, you can buy me a coffee

Please also check my other articles on my website https://weekendtutorial.com

Edit

In Example 1 -

Since array is also an object so we could optimise the code further -

const dayNum = new Date().getDay();
const days = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"
];
console.log(days[dayNum]); // Sunday
Enter fullscreen mode Exit fullscreen mode

In Example 2 -

We could have club the object like this -

let pageName = document.querySelector('#my-div').dataset.pageName;
let dataPageMapper = {
  homepage: {
     page: 'Home',
     layout: 'index'
  },
  productpage: {
     page: 'Product',
     layout: 'pdp'
  },
  blogpage: {
     page: 'Blog',
     layout: 'blog'
  } 
};

let pageObj = dataPageMapper.hasOwnProperty(pageName) && dataPageMapper[pageName];

let ans = pageObj.page + '_' + pageObject.layout;
console.log(ans);
Enter fullscreen mode Exit fullscreen mode

Above is also fine, but actual example was taken considering the possibility of when the clubbing the object is least feasible.

Of course, if the object are coming from different files or place, we can still create another by clubbing them but that will introduce another problem viz. code duplicacy which should be avoided.

Top comments (16)

Collapse
 
vbarzana profile image
Victor A. Barzana • Edited

Maybe it would be better to use an array for the days example considering that Su-Sa = 0-6.

const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
console.log(days[new Date().getDay()])
Enter fullscreen mode Exit fullscreen mode
Collapse
 
frankwisniewski profile image
Frank Wisniewski

The day of week was just a example....

console.log( new Date().toLocaleDateString("En-en",{ weekday: 'long' }));
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ajayv1 profile image
Ajay Kumar Verma

@frankwisniewski Above was just an example to illustrate how we can acheive the switch statement through JS object.

Thanks for one liner though!

Collapse
 
vbarzana profile image
Victor A. Barzana

Yes sir, I agree with your comment, what I am trying to correct here is about replacing the switch, think of days of the week as fruits, and you will get my point.

Thread Thread
 
frankwisniewski profile image
Frank Wisniewski • Edited

Yes Sir, an array works well for months, days, etc.
The weekday example is not good...

Thread Thread
 
ajayv1 profile image
Ajay Kumar Verma

Updating the code.

Collapse
 
vbarzana profile image
Victor A. Barzana

For example 2, having separate Objects to store the data related to pages is a bit misleading and accessing them by the lowercased output of another property could be buggy and not work as expected, what about storing all data in the same place?

const pageName = document.querySelector('#my-div').dataset.pageName;
const dataPageMapper = {
  homepage: {
        title: 'Home',
        layout: 'index'
  },
 productpage: {
        title: 'Product',
        layout: 'pdp'
  },
  blogpage: {
        title: 'Blog',
        layout: 'blog'
  }
};
const currentPage = dataPageMapper[pageName];
// and be careful with accessing properties of an object that doesn't match your pages config
console.log(currentPage.title + '_' + currentPage.layout);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ajayv1 profile image
Ajay Kumar Verma

Actually, I have taken the more general case when the clubbing is not possible i.e it could be the first object and 2nd object are seperate and coming from different files or place.

for this case though, we could have club the data.

Thanks for the suggestion!

Collapse
 
ajayv1 profile image
Ajay Kumar Verma

Yes Victor, As array is also an object in javascript so it would also work the same. Thanks for the suggestion. I'll update the code.

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Example 1 would be simpler with an array.

Also, you can add js after the opening backticks on the code blocks to switch on syntax highlighting

Collapse
 
ajayv1 profile image
Ajay Kumar Verma

Yes @jonrandy As array is also an object in javascript so it would also work the same. Thanks for the suggestion.

Collapse
 
jwhenry3 profile image
Justin Henry

I like to use the object map pattern to avoid switch statements, as it does allow adding keys and values to increase the flexibility of the condition, and allows direct access to map values rather than relying on logic branches (which could cause complexity issues for grading platforms). Another thought is parallel arrays, but that requires a little more care when constructing as you will need to know what each index means in the parallel arrays. being able to access map[key].property to avoid branches are really nice.

Collapse
 
ajayv1 profile image
Ajay Kumar Verma

Yes Justin, I also do the same and thought of sharing this point through the article. I am new to dev.to, Its really nice to share and get the comments.

Collapse
 
lexlohr profile image
Alex Lohr

Switch statements can shine if multiple comparators should yield the same result. Otherwise objects, Maps (if the comparators are not strings) or if/else/ternary chains are better.

Collapse
 
ajayv1 profile image
Ajay Kumar Verma

Alex, didn't get the point.

You mean if comparators are string then switch would be better? I don't think so, as matching the string the object key will take same amount of time same as switch.

Collapse
 
lexlohr profile image
Alex Lohr

Maybe an oversimplified example may help:

const positionInWeek = (dayOfWeek) => {
  switch (dayOfWeek) {
    case "Monday":
    case "Tuesday":
      return "Start of the week"
    case "Wednesday":
    case "Thursday":
    case "Friday":
      return "Middle of the week"
    case "Saturday":
    case "Sunday":
      return "End of the week"
    default:
      throw new Error("Not a week day")
  }
}
Enter fullscreen mode Exit fullscreen mode

This would be harder to understand in an object or if-else-if-chain.