JavaScript Enum: The Best Way To Avoid Magic String

Are you tired of using hard-coded strings and numbers in code? JavaScript Enum helps improve code readability, prevent mistakes, and enforce consistency by replacing the hard-coded value with name constants.

An enumeration is a data type that consists of a set of named values. In simple terms, it is a collection of related constants each with a name and a value. We use Enums to store a set of predefined values, which simplifies the code and makes it easier to read and understand.

This blog post will explore the: 

  • What is an enum (enumeration)?
  • How do I create an Enum?
  • Add Values to Enum
  • Get keys and values from Enums
  • Advantages of using Enum in the application
  • Real-time use cases

Let’s look into each item in detail.

What is JavaScript Enum?

A JavaScript Enum or Enumeration object is a collection of related constants, each with a name and a value. There is no built-in data type Enum in JavaScript, like in other programming languages. We have to create our own Enums using objects or symbols. Additionally, JavaScript Enums do not have a built-in way of automatically assigning integer values to the values in the Enum.

const Color = {
  Red: 'Red',
  Green: 'Green',
  Blue: 'Blue'
};

How to create JavaScript Enums?

It is possible to create Enums using objects or symbols. Let’s see how to create Enum in JavaScript using an object literal. This is the simplest method to create an Enum in JavaScript.

Let’s first create a string Enum using the object literal. To create an Enum in JavaScript using an object literal, define a constant variable and assign a JavaScript String or object to it, as shown in the following example:

const OrderState = {
  NEW: 'New',
  PROCESSING: 'Processing',
  SHIPPED: 'Shipped',
  COMPLETED: 'Completed'
};

console.log(OrderState.NEW)
// Output: "New"

In the above code example, JavaScript Enums are created using object literal, so no need to convert Enum to strings.

Create a read-only JavaScript Enum

Note that this standard approach doesn’t prevent you from modifying the Enum values of the OrderState. It’s always best practice to create an Enum immutable. To create a read-only Enum, you can use Object.freeze() method to make the object properties immutable (once created, you can’t change them):

const OrderState = Object.freeze({
  NEW: 'New',
  PROCESSING: 'Processing',
  SHIPPED: 'Shipped',
  COMPLETED: 'Completed'
});

Create a JavaScript Enum with integer value

JavaScript Enums do not have any standard way of automatically assigning integer values to the values in the Enum. We can use a custom approach to assign an integer value to each item.

const IssueSeverity = Object.freeze(
  {
    Blocker: { name: 'Blocker', value: 1 },
    Critical: { name: 'Critical', value: 2 },
    Major: { name: 'Major', value: 3 },
    Minor: { name: 'Minor', value: 4 }
  });

// Get Enum value
console.log(IssueSeverity.Major.name)
// Output: "Major"

// Get Enum integer value
console.log(IssueSeverity.Major.value)
// Output: 3

How to add values to JavaScript Enumeration?

There is no built-in method to add an entry to an Enum object. You need to add properties to the object. Let’s add the new order state "Cancelled" to the OrderState Enum. Here is an example:

const OrderState = Object.freeze({
  NEW: 'New',
  PROCESSING: 'Processing',
  SHIPPED: 'Shipped',
  COMPLETED: 'Completed',
  CANCELLED: 'Cancelled'
});

Get string value from an Enum

There are two ways you can access Enum values.

  • Using the dot notation, you can access the Enum value.
  • You can use square bracket notation as well; however, this will defeat the purpose of an Enum. Because you have to give the name as a string. This is useful if you have to read the Enum value based on some input.

For example:

console.log(OrderState.COMPLETED)
// Output: "Completed"

console.log(OrderState['COMPLETED'])
// Output: "Completed"

Get Enum key by value

You can use any one of the methods explained above to get the value from an Enum. But what if you wanted to get the key name from the value? Let’s see the following example:

const HttpStatusCode = Object.freeze(
  {
    OK: 200,
    NOT_FOUND: 404,
    INTERNAL_ERROR: 500,
    MOVED_PERMANENTLY: 301
  });

let valueToFind = 500;
console.log(Object.keys(HttpStatusCode).filter(k => HttpStatusCode[k] === valueToFind)[0])
// Output: "INTERNAL_ERROR"

Using the JavaScript object.keys() method, you can get all of the Enum keys. In this example, we use the filter() JavaScript array methods to filter keys. In the filter() method, you can compare each Enum value and determine whether it matches the value that you are looking for. The filter() method always returns the result as an array. So, we have to take the first matching Enum item using array index 0.

The key name as a string is the return value when the Enum contains the key. The return value is "undefined" when the Enum does not contain the key.

JavaScript Object Keys
JavaScript Object.keys() Method

JavaScript Enum to string

To convert these Enum-like objects to strings, you can implement a method that returns the string representation based on the enum value.

const HttpStatusCode = {
  OK: 200,
  NOT_FOUND: 404,
  INTERNAL_ERROR: 500,
  MOVED_PERMANENTLY: 301
};

HttpStatusCode.toString = function (enumValue) {
  return Object.keys(HttpStatusCode).filter(k => HttpStatusCode[k] === enumValue)[0]
};

const statusCode = HttpStatusCode.INTERNAL_ERROR;
console.log(HttpStatusCode.toString(statusCode)); 
// Output: "INTERNAL_ERROR"

We define a toString() method that takes an Enum value as input and iterates over the Enum-like object to find the corresponding key (string representation).

It returns null or you can handle it based on your requirements when the given Enum value is not found in the Enum. We add the JavaScript toString() method after creating the Enum, so we do not use Object.freeze() here.

Use cases for Enums in JavaScript

1. Use in switch statements

We can use Enums in switch statements to improve the code readability and to guarantee that we cover all the possible values in the Enums in the switch case. For example:

switch (color) {
    case Color.RED: 
    	// do something 
    	break; 
  	case Color.GREEN: 
    	// do something 
    	break; 
  	case Color.BLUE: 
    	// do something 
    	break; 
  	default: 
        // handle error 
        break; 
}

2. Use in function arguments and return values

Enums can be used in function arguments and return values to enforce consistency and prevent mistakes. For example:

function getColor(color) {
    switch (color) {
        case Color.RED:
            return 'red';
        case Color.GREEN:
            return 'green';
        case Color.BLUE:
            return 'blue';
        default:
            throw new Error('Invalid color');
    }
}

3. Use in defining constant values

Not just with string, using Enum you can avoid magic numbers as well in your code. As shown in the following example, you can create an Enum with numbers:

const HttpStatusCode = Object.freeze({
  OK: 200,
  NOT_FOUND: 404,
  INTERNAL_ERROR: 500,
  MOVED_PERMANENTLY: 301
});

This text defines the HttpStatusCode Enum with HTTP status code numbers. You can use the above HttpStatusCode Enum like this to handle HTTP response status instead of using the hard-coded number 200.

let response = getData();
if (response.status === HttpStatusCode.OK) {
  // do something with the data...
} else {
  // Handle exception.
}

Advantages of using Enums in JavaScript

1. Improved code readability by avoiding magic string in JavaScript

Enums make the code more readable by allowing you to use meaningful names for constant values instead of magic numbers or strings. Using magic strings and numbers in code is one of the most common anti-patterns.

Assume you have data export capabilities in your program that support CSV and Excel formats. You have to write code something like this:

const exportContent = (exportType) => {
  if (exportType === 'CVS') {
    // Export content in CSV Format
  }
  else if (exportType === 'Excel') {
    // Export content in CSV Format
  }
  else {
    // Export type is not supporrted.
  }
}

Let’s see how to replace this magic string "CSV" and "Excel" from code with a JavaScript Enum. Create an Enum ExportType with two values "CSV" and "Excel". Once Enum is created, you can replace the existing hard-coded string with this Enum as shown in the following example:

const ExportType = Object.freeze(
  {
    CSV: 'CSV',
    Excel: 'Excel'
  });
  
  const exportContent = (exportType) => {
  if (exportType === ExportType.CSV) {
    // Export content in CSV Format
  }
  else if (exportType === ExportType.Excel) {
    // Export content in CSV Format
  }
  else {
    // Export type is not supporrted.
  }
}

Add a clear JavaScript comment to explain what are the types supported.

2. Enums are objects with a finite set of properties

Enums in JavaScript are objects with a finite set of properties, which makes it easy to check if a value is part of the Enum or not. This helps to enforce consistency and prevent errors, such as typos or incorrect values.

3. Enums can be used for better error handling

By using Enums in JavaScript, developers can handle errors more effectively. When we use an Enum in a switch statement, the compiler enforces that the switch case covers all possible values in the Enum. This helps to prevent bugs and makes it easier to maintain the code.

4. Enums can help reduce bugs and improve maintainability

By using Enums in JavaScript, developers can reduce the likelihood of bugs and improve the maintainability of the code. This is because Enums make the code more readable, enforce consistency, and prevent mistakes.

Conclusion

In conclusion, JavaScript Enum improves code readability, ensures consistency, helps in error handling, lowers bugs, and enhances maintainability.

Because JavaScript lacks built-in Enum types, we covered how to build one using object literals in this blog post. To create a read-only Enum or an Enum with an integer value, we can use the Object.freeze() method. This method prevents any changes to the properties of an object.

In addition to Enum creation, we covered how to add values to an Enum, get keys and values, and get a key based on its value.

Enums are an excellent option for creating bug-free, maintainable code. Enums can help you write better code by avoiding magic strings when dealing with switch statements, function arguments, and return values.

In which situation are you going to use JavaScript Enum?

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Scroll to Top