Enum

The Power of Enums in Simplifying Code

How Enums Can Simplify Code

enum PlanetType { terrestrial, gas, ice }

This is a basic enum that everyone knows. But what if your enum could:

  • Define itself in JSON when received from a server

  • Automatically translate into different languages

  • List all its values dynamically

  • Search for values within its own methods

  • Shorten conditional statements significantly

In this article, I’ll show you a different way to use enums, turning a simple definition into a powerful and efficient coding tool.

Flutter is an object-oriented framework, and encapsulation is a key principle in OOP. Encapsulation hides the implementation details of an object and only allows interaction through public methods. This helps protect internal data, reduce errors, and improve maintainability.

Therefore, we can incorporate all these useful functionalities into a single enum, making it easier to use without worrying about its internal logic.

Defining Custom Fields in JSON

Defining a custom field in JSON is introduced in the official documentation of json_serializable: 🔗 json_serializable - Enums

Below is an example of how to set up an enum for json_serializable. The enum retrieves data from JSON based on the 'code' field and converts it into an enum value.

For example, with the following JSON:

{ "code" : 1 }

The corresponding enum value will be:

StateEnum.loading

We can replace 'code' with any other field, such as 'title', depending on the requirements.

Example Code:

@JsonEnum(valueField: 'code')
enum StateEnum {
  notWorkingReady(0, "notWorkingReady"),
  loading(1, "loading"),
  notWorkingSuccess(3, "notWorkingSuccess"),
  notWorkingFailure(2, "notWorkingFailure");

  const StateEnum(this.code, this.title);

  final int code;
  final String title;
}

Shortening Conditional Code

The second benefit that enums provide is reducing conditional code, making it easier to understand. Let's take a look at the following example:

@JsonEnum(valueField: 'code')
enum StateEnum {

    notWorkingReady( 0, "notWorkingReady"),
    loading( 1, "loading"),
    notWorkingSuccess( 3, "notWorkingSuccess"),
    notWorkingFailure( 2, "notWorkingFailure");
    
    // @override
    // int compareTo(PaddingWhiteLineEditEnum other) => code - other.code;
    
    const StateEnum( this.code, this.title);
    
    final int code;
    final String title;

    bool get isLoading => this == StateEnum.loading;

}

Writing concise conditions makes the code more readable and easier to understand, as shown below:

New approach:

if (state.isLoading) {
  
}

Old approach:

if (state == StateEnum.loading) {
  
}

Language Translation

String get interpret => switch (this) {
      StateEnum.notWorkingReady => "Translate notWorkingReady",
      StateEnum.loading => "Translate loading",
      _ => "Translate other",
  };

I will write a separate article on. multi-language translation. You can check it out here

Multi-Language

Retrieve Data from Enum Fields

Suppose I have the code field value and I want to find out which enum it corresponds to. I can create a function like this:

static ({StateEnum? getEnum, String? string})? getByCode(int? code) {
    try {
        final e = StateEnum.values.firstWhere((element) => element.code == code);
        return (getEnum: e, string: e.interpret);
    } catch (e) {
        return null;
    }
}

Using Mason to Speed Up Enum Creation

With all the benefits listed above, using full-featured enums helps us write cleaner and faster code.

To generate a predefined template for your enums, consider using Mason. (If you're unfamiliar with Mason, check out this guide: Boost Your Flutter Development Efficiency with Mason)

Mason

You can also check out my enum template and create a custom one for yourself and your colleagues: dr_enum on BrickHub

Buy Me a Coffee | Support Me on Ko-fi

Last updated