Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add methods or values to enum in dart

Tags:

dart

Starting with Dart 2.6 you can define extensions on classes (Enums included).

enum Cat {
  black,
  white
}

extension CatExtension on Cat {

  String get name {
    switch (this) {
      case Cat.black:
        return 'Mr Black Cat';
      case Cat.white:
        return 'Ms White Cat';
      default:
        return null;
    }
  }

  void talk() {
    print('meow');
  }
}

Example:

Cat cat = Cat.black;
String catName = cat.name;
cat.talk();

Here's one more live example (uses a constant map instead of a switch): https://dartpad.dartlang.org/c4001d907d6a420cafb2bc2c2507f72c


Dart enums are used only for the simplest cases. If you need more powerful or more flexible enums, use classes with static const fields like shown in https://stackoverflow.com/a/15854550/217408

This way you can add whatever you need.


Nope. In Dart, enums can only contain the enumerated items:

enum Color {
  red,
  green,
  blue
}

However, each item in the enum automatically has an index number associated with it:

print(Color.red.index);    // 0
print(Color.green.index);  // 1

You can get the values by their index numbers:

print(Color.values[0] == Color.red);  // True

See: https://www.dartlang.org/guides/language/language-tour#enums


It may not be "Effective Dart" , I add a static method inside a Helper class ( there is no companion object in Dart) .

In your color.dart file

enum Color {
  red,
  green,
  blue
}

class ColorHelper{

  static String getValue(Color color){
    switch(color){
      case Color.red: 
        return "Red";
      case Color.green: 
        return "Green";
      case Color.blue: 
        return "Blue";  
      default:
        return "";
    }
  }

}

Since the method is in the same file as the enum, one import is enough

import 'package:.../color.dart';

...
String colorValue = ColorHelper.getValue(Color.red);

extension is good, but it cannot add static methods. If you want to do something like MyType.parse(string), consider using a class with static const fields instead (as Günter Zöchbauer suggested before).

Here is an example

class PaymentMethod {
  final String string;
  const PaymentMethod._(this.string);

  static const online = PaymentMethod._('online');
  static const transfer = PaymentMethod._('transfer');
  static const cash = PaymentMethod._('cash');

  static const values = [online, transfer, cash];

  static PaymentMethod parse(String value) {
    switch (value) {
      case 'online':
        return PaymentMethod.online;
        break;
      case 'transfer':
        return PaymentMethod.transfer;
        break;
      case 'cash':
        return PaymentMethod.cash;
      default:
        print('got error, invalid payment type $value');
        return null;
    }
  }

  @override
  String toString() {
    return 'PaymentMethod.$string';
  }
}

I found this much handier than using a helper function.

final method = PaymentMethod.parse('online');
assert(method == PaymentMethod.online);

I did this (inspired form the accepted answer by @vovahost)

enum CodeVerifyFlow {
  SignUp, Recovery, Settings
}

extension CatExtension on CodeVerifyFlow {
  String get name {
    return ["sign_up", "recovery", "settings"][index];
  }
}

// use it like
CodeVerifyFlow.SignUp.name

thank me later!


As an improvement on the other suggestions of using Extensions, you can define your assigned values in a list or map, and the extension will be concise.

enum Numbers {
  one,
  two,
  three,
}

// Numbers.one.value == 1

example with list

extension NumbersExtensionList on Numbers {
  static const values = [1, 2, 3];
  int get value => values[this.index];
}

example with map

extension NumbersExtensionMap on Numbers {
  static const valueMap = const {
    Numbers.one: 1,
    Numbers.two: 2,
    Numbers.three: 2,
  };
  int get value => valueMap[this];
}

Note: This approach has the limitation that you can not define a static factory method on the Enum, e.g. Numbers.create(1) (as of Dart 2.9). You can define this method on the NumbersExtension, but it would need to be called like NumbersExtension.create(1)


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!