Dart Flutter Tips

Enhanced enums

Since Dart 2.17, we can declare enums with members.
Plague Fox 1 min read
Enhanced enums
Photo by Ales Nesetril / Unsplash

Since Dart 2.17, we can declare enums with members.

/// {@template status}
/// Status enumeration
/// {@endtemplate}
enum Status with Comparable<Status> {
  /// Loading
  loading('Loading'),

  /// Idle
  idle('Idle'),

  /// Error
  error('Error');

  /// {@macro status}
  const Status(this.value);

  /// Creates a new instance of [Status] from a given string.
  static Status fromValue(Object? value, {Status? fallback}) {
    final status = value?.toString().split('.').last.trim().toLowerCase();
    switch (status) {
      case 'loading':
        return loading;
      case 'idle':
        return idle;
      case 'error':
        return error;
      default:
        return fallback ?? (throw ArgumentError.value(value));
    }
  }

  /// Value of the enum
  final String value;

  /// Pattern matching
  T map<T>({
    required T Function() loading,
    required T Function() idle,
    required T Function() error,
  }) {
    switch (this) {
      case Status.loading:
        return loading();
      case Status.idle:
        return idle();
      case Status.error:
        return error();
    }
  }

  /// Pattern matching
  T maybeMap<T>({
    required T Function() orElse,
    T Function()? loading,
    T Function()? idle,
    T Function()? error,
  }) =>
      map<T>(
        loading: loading ?? orElse,
        idle: idle ?? orElse,
        error: error ?? orElse,
      );

  /// Pattern matching
  T? maybeMapOrNull<T>({
    T Function()? loading,
    T Function()? idle,
    T Function()? error,
  }) =>
      maybeMap<T?>(
        orElse: () => null,
        loading: loading,
        idle: idle,
        error: error,
      );

  @override
  int compareTo(Status other) => index.compareTo(other.index);

  @override
  String toString() => value;
}
Share
Comments
More from Plague Fox
Form State Management
Dart Flutter Article Tips

Form State Management

Flutter's SDK already has everything you need to manage complex forms — no packages required. Listenable.merge turns any combination of ValueNotifier, TextEditingController, FocusNode, and ChangeNotifier into a single reactive form controller.
Plague Fox 4 min read
Safe Resource Cleanup with Closure Chains
Dart Flutter Article

Safe Resource Cleanup with Closure Chains

Dart has no defer, no RAII, no scope guards. When multi-step async initialization fails midway, you need to unwind only what was set up — in reverse order, crash-safe. Here's a 6-line closure chain pattern that gives you transactional init, safe teardown, and cancellation support for free.
Plague Fox 5 min read

Plague Fox

Engineer by day, fox by night. Talks about Flutter & Dart.

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Plague Fox.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.