Creating Factory Constructors for enums with Dart 2.17's enhanced enums

Introduction

Recently, I’ve been developing a Flutter application personally, and I found myself in a situation where I wanted to generate an enum from a string.

Previously, I defined methods for enums using Extensions. However, remembering that enums were enhanced in Dart 2.17, I researched and found that it was possible to achieve this without Extensions. I wanted to summarize this for personal reference.

Enhanced enums

What are enhanced enums?

First, let’s briefly touch on enhanced enums. Borrowing code from the official page, enhanced enums allow you to define instance variables, methods, and constructors within the enum itself, as shown below:

enum Vehicle implements Comparable<Vehicle> {
  car(tires: 4, passengers: 5, carbonPerKilometer: 400),
  bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
  bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

  const Vehicle({
    required this.tires,
    required this.passengers,
    required this.carbonPerKilometer,
  });

  final int tires;
  final int passengers;
  final int carbonPerKilometer;

  int get carbonFootprint => (carbonPerKilometer / passengers).round();

  @override
  int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}

However, there are some constraints:

Factory Constructor

While the official page doesn’t provide an example, Factory constructors can also be defined:

enum Color {
  red,
  blue,
  none; // Note the semicolon!

  factory Color.from(String value) {
    switch (value) {
      case 'red':
        return Color.red;
      case 'blue':
        return Color.blue;
      default:
        return Color.none;
    }
  }
}

Color.from('red') // Returns Color.red

Due to the constraints of enhanced enums, it’s not possible to return null. Hence, it’s crucial to provide some sort of handling (like throwing an error or returning a dedicated enum) for unexpected arguments.

Conclusion

Enums have become much more convenient with enhanced enums. I look forward to using them more frequently and updating my existing code accordingly.

Related Posts