Launch Club

Enhanced Enums in Dart

Dart

Published Nov 27, 2023

Marcus Ng

Marcus Ng

Enhanced enums were introduced in Dart 2.17 and are similar to regular classes, but they have a fixed set of instances.

They are more powerful than traditional enums as they can have properties, methods, and constructors.

Let’s pretend we’re building a weather app with an enum of seasons.

enum Season {
  spring,
  summer,
  fall,
  winter
}

In the past, if we wanted to add a corresponding image url and an average temperature to each season, we had a couple of options.

  1. Create an extension.
/// Extension example.
extension SeasonX on Season {
  // Image url example.
  String getImageUrl(Season season) {
    switch (season) {
      case Season.spring:
        return '<spring_image_url>';
      case Season.summer:
        return '<summer_image_url>';
      case Season.fall:
        return '<fall_image_url>';
      case Season.winter:
        return '<winter_image_url>';
	  }
  }

	// ...
}
  1. Turn Season into a class with factory constructors and three members (SeasonType type, String imageUrl, and double averageTemp).
/// Class example.
/// Note that I've renamed the `Season` enum to `SeasonType`.
class Season {
  const Season({
    required this.type,
    required this.imageUrl,
    required this.averageTemp,
  });

  factory Season.spring() => const Season(
        type: SeasonType.spring,
        imageUrl: '<spring_image_url>',
        averageTemp: 54,
      );

  // ...

  final SeasonType type;
  final String imageUrl;
  final double averageTemp;
}

With enhanced enums, we can simplify this by adding the member variables directly into the enum.

enum Season {
  spring('<spring_image_url>', 54),
  summer('<summer_image_url>', 81),
  fall('<fall_image_url>', 48),
  winter('<winter_image_url>', 32);

  const Season(this.imageUrl, this.averageTemp);

  final String imageUrl;
  final double averageTemp;

  void info() => print('''
    ${this.name}
    $imageUrl
    Average temperature: $averageTemp°F
    ''');
}

Now we can instantiate each Season while having access to the member variables and methods!

void main() {
  Season.spring.info();
  Season.summer.info();
  Season.fall.info();
  Season.winter.info();
}

// === Console ===
// spring
// <spring_image_url>
// Average temperature: 54°F

// summer
// <summer_image_url>
// Average temperature: 81°F

// fall
// <fall_image_url>
// Average temperature: 48°F

// winter
// <winter_image_url>
// Average temperature: 32°F

Flutter and Dart

made simple.

Everything you need to build production ready apps.

No spam. Just updates. Unsubscribe whenever.