DEV Community

Javeed Ishaq
Javeed Ishaq

Posted on

Mastering Dart Enums: From Basic Lists to Supercharged Classes

If you’ve ever written status == 'active' in your code and then spent hours debugging a typo because you wrote 'actve', you know why we need Enums.

Enums (Enumerations) are just a fancy way of saying "a fixed list of options." They stop you from making silly spelling mistakes.

But in Dart, Enums have evolved. They aren't just simple lists anymore; they are Enhanced Enums. They can hold data, run logic, and even talk to your database.

Let's break down how they work, why they look a bit weird sometimes, and how to master them.


Level 1: The Basic Enum (The "Shopping List")

In the old days (or other languages), an Enum was just a list of names.

enum BannerStatus {
  active,
  inactive,
  scheduled,
  expired
}
Enter fullscreen mode Exit fullscreen mode

This is great for your code:
if (status == BannerStatus.active) works perfectly.
if (status == BannerStatus.activ) throws an error immediately (which is good!).

The Problem:
Your database doesn't know what BannerStatus.active is. Your database usually speaks in Strings (text) or Integers (numbers).

  • Your Code: BannerStatus.active (CamelCase)
  • Your Database: "ACTIVE" (UpperSnakeCase)

How do you connect them? You used to have to write big, ugly switch statements everywhere.


Level 2: Enhanced Enums (The "Sticky Note" Solution)

Dart introduced Enhanced Enums to solve this. Think of it like this:

We want to attach a "Sticky Note" to every Enum option containing the exact text the database expects.

Here is the syntax that confuses people at first:

enum BannerStatus {
  // 1. The Name      2. The Sticky Note
  active             ('ACTIVE'),
  inactive           ('INACTIVE'),
  scheduled          ('SCHEDULED'),
  expired            ('EXPIRED'); // Note the semicolon!

  // 3. The Glue (Constructor)
  const BannerStatus(this.value);

  // 4. The Storage
  final String value;
}
Enter fullscreen mode Exit fullscreen mode

How it works (The "Magic" Explained)

When you write active('ACTIVE'), you are actually calling a constructor.

  1. active: This is the variable name you use in your Dart code.
  2. ('ACTIVE'): You are passing this string into the constructor.
  3. this.value: The constructor takes that string and saves it into the value field.

Now, BannerStatus.active carries a hidden backpack containing the string "ACTIVE".

print(BannerStatus.active);       // Output: BannerStatus.active
print(BannerStatus.active.value); // Output: ACTIVE
Enter fullscreen mode Exit fullscreen mode

Level 3: Talking to the Database (JSON)

Now that our Enums hold values, we can easily convert them back and forth.

1. The Sender (toJson)

When sending data to your API or Database, you don't send the Dart object; you send the "Sticky Note" value.

  /// Converts the enum to a string value for JSON serialization
  String toJson() => value;
Enter fullscreen mode Exit fullscreen mode

Usage:

Map<String, dynamic> data = {
  'id': 123,
  'status': BannerStatus.active.toJson(), // Sends "ACTIVE"
};
Enter fullscreen mode Exit fullscreen mode

2. The Receiver (fromJson)

When data comes back from the database, it's just a dumb string like "ACTIVE". We need to find the matching Enum.

  static BannerStatus fromJson(String value) {
    return BannerStatus.values.firstWhere(
      (status) => status.value == value,
      orElse: () => BannerStatus.inactive, // Safety Net!
    );
  }
Enter fullscreen mode Exit fullscreen mode

How this works:

  1. It looks through all options (BannerStatus.values).
  2. It checks each one's "sticky note" (status.value).
  3. If it finds a match, it returns that Enum.
  4. Safety Net (orElse): If the database sends garbage (e.g., "DELETED" which we don't have), it defaults to inactive instead of crashing your app.

Level 4: Superpowers (Getters)

Since Enhanced Enums are basically Classes, you can add logic to them!

Instead of writing if statements all over your UI, put the logic inside the Enum.

enum BannerStatus {
  active('ACTIVE'),
  inactive('INACTIVE'),
  scheduled('SCHEDULED'),
  expired('EXPIRED');

  const BannerStatus(this.value);
  final String value;

  // Computed Property
  bool get isVisible {
    return this == BannerStatus.active;
  }

  // UI Helper
  String get label {
    switch (this) {
      case BannerStatus.active: return 'Live Now';
      case BannerStatus.scheduled: return 'Coming Soon';
      case BannerStatus.expired: return 'Finished';
      case BannerStatus.inactive: return 'Draft';
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Usage in Flutter UI:

Text(
  status.label, // Prints "Live Now"
  style: TextStyle(
    color: status.isVisible ? Colors.green : Colors.grey,
  ),
)
Enter fullscreen mode Exit fullscreen mode

Summary

  1. Basic Enums are just lists of names.
  2. Enhanced Enums let you attach data (like database strings) to those names using a Constructor.
  3. toJson extracts that data to send to the server.
  4. fromJson finds the correct Enum based on data from the server.
  5. Use Getters to keep your UI code clean and logic centralized.

Now you can write Enums that are powerful, safe, and easy to use! 🚀

Top comments (0)