Dart How to get the name of an enum as a String

EnumsDart

Enums Problem Overview


Before enums were available in Dart I wrote some cumbersome and hard to maintain code to simulate enums and now want to simplify it. I need to get the name of the enum as a string such as can be done with Java but cannot.

For instance little test code snippet returns 'day.MONDAY' in each case when what I want is 'MONDAY"

enum day {MONDAY, TUESDAY}
print( 'Today is $day.MONDAY');
print( 'Today is $day.MONDAY.toString()');

Am I correct that to get just 'MONDAY' I will need to parse the string?

Enums Solutions


Solution 1 - Enums

Dart 2.7 comes with new feature called Extension methods. Now you can write your own methods for Enum as simple as that!

enum Day { monday, tuesday }

extension ParseToString on Day {
  String toShortString() {
    return this.toString().split('.').last;
  }
}

main() {
  Day monday = Day.monday;
  print(monday.toShortString()); //prints 'monday'
}

Solution 2 - Enums

Bit shorter:

String day = theDay.toString().split('.').last;

Solution 3 - Enums

Sadly, you are correct that the toString method returns "day.MONDAY", and not the more useful "MONDAY". You can get the rest of the string as:

day theDay = day.MONDAY;      
print(theDay.toString().substring(theDay.toString().indexOf('.') + 1));

Hardly convenient, admittedly.

Another way to get the enum name as a string, one which is shorter, but also less efficient because it creates an unnecessary string for first part of the string too, is:

theDay.toString().split('.').last

If performance doesn't matter, that's probably what I'd write, just for brevity.

If you want to iterate all the values, you can do it using day.values:

for (day theDay in day.values) {
  print(theDay);
}

Solution 4 - Enums

Simplest way to get the name of an enum is a standard method from the flutter/foundation.dart

describeEnum(enumObject)

enum Day {
  monday, tuesday, wednesday, thursday, friday, saturday, sunday
}

void validateDescribeEnum() {
  assert(Day.monday.toString() == 'Day.monday');
  assert(describeEnum(Day.monday) == 'monday');
}

Solution 5 - Enums

Update Dart 2.15:
enum Day {
  monday,
  tuesday,
}

You can use name property on the enum.

String monday = Day.monday.name; // 'monday'

Old solution:

1. Direct way:

var dayInString = describeEnum(Day.monday);
print(dayInString); // prints 'monday'

2. Using Extension:

extension DayEx on Day {
  String get name => describeEnum(this);
}

You can use it like:

void main() {
  Day monday = Day.monday;
  print(monday.name); // 'monday'
}

Solution 6 - Enums

There is a more elegant solution:

enum SomeStatus {
  element1,
  element2,
  element3,
  element4,
}

const Map<SomeStatus, String> SomeStatusName = {
  SomeStatus.element1: "Element 1",
  SomeStatus.element2: "Element 2",
  SomeStatus.element3: "Element 3",
  SomeStatus.element4: "Element 4",
};

print(SomeStatusName[SomeStatus.element2]) // prints: "Element 2"

Solution 7 - Enums

enum day {MONDAY, TUESDAY}
print( 'Today is ${describeEnum(day.MONDAY)}' );

console output: Today is MONDAY

Solution 8 - Enums

Sometimes I need to separate ui-value and real-value, so I defined keys and values using Map. This way, we have more flexiblity. And by using extension (since Dart 2.7), I made a method to read its key and value.

enum Status {
  progess,
  done,
}

extension StatusExt on Status {
  static const Map<Status, String> keys = {
    Status.progess: 'progess',
    Status.done: 'done',
  };

  static const Map<Status, String> values = {
    Status.progess: 'In Progress',
    Status.done: 'Well done',
  };

  String get key => keys[this];
  String get value => values[this];

  // NEW
  static Status fromRaw(String raw) => keys.entries
      .firstWhere((e) => e.value == raw, orElse: () => null)
      ?.key;
}

// usage 1
Status status = Status.done;
String statusKey = status.key; // done
String statusValue = status.value; // Well done

// usage 2 (easy to make key and value list)
List<Status> statuses = Status.values;
List<String> statusKeys = statuses.map((e) => e.key).toList();
List<String> statusValues = statuses.map((e) => e.value).toList();

// usage 3. create Status enum from string.
Status done1 = StatusExt.fromRaw('done') // Status.done
Status done2 = StatusExt.fromRaw('dude') // null

Solution 9 - Enums

I use structure like below:

abstract class Strings {
  static const angry = "Dammit!";
  static const happy = "Yay!";
  static const sad = "QQ";
}

Solution 10 - Enums

I use the functions below to get the name of the enum value and, vise versa, the enum value by the name:

String enumValueToString(Object o) => o.toString().split('.').last;

T enumValueFromString<T>(String key, Iterable<T> values) => values.firstWhere(
      (v) => v != null && key == enumValueToString(v),
      orElse: () => null,
    );

When using Dart 2.7 and newer, extension methods would work here (as well as for any other Objects):

extension EnumX on Object {
  String asString() => toString().split('.').last;
}

The implementation above is not dependant on the specific enums.

Usage examples:

enum Fruits {avocado, banana, orange}
...
final banana = enumValueFromString('banana', Fruits.values);
print(enumValueToString(banana)); // prints: "banana"
print(banana.asString()); // prints: "banana"

Edit from 2020-04-05: Added nullability checks. values parameter could be Iterable, not necessarily List. Added extensions method implementation. Removed <Fruits> annotation from the example to show that the class name duplication is not required.

Solution 11 - Enums

I got so over this I made a package:

https://pub.dev/packages/enum_to_string

Also has a handy function that takes enum.ValueOne and parses it to "Value one"

Its a simple little library but its unit tested and I welcome any additions for edge cases.

Solution 12 - Enums

Dart 2.15 includes an extension to make this easy:

enum day {MONDAY, TUESDAY}
print( 'Today is ${day.MONDAY.name}');

Until the changes in https://github.com/dart-lang/sdk/commit/18f37dd8f3db6486f785b2c42a48dfa82de0948b are rolled out to a stable version of Dart, the other clever but more complex answers here are very useful.

Solution 13 - Enums

One more way:

enum Length {
  TEN,
  TWENTY,
  THIRTY,
  NONE,
}

extension LengthValue on Length {
  static const _values = [10, 20, 30, 0];

  int get value => _values[this.index];
}

Solution 14 - Enums

My approach is not fundamentally different, but might be slightly more convenient in some cases:

enum Day {
  monday,
  tuesday,
}

String dayToString(Day d) {
  return '$d'.split('.').last;
}

In Dart, you cannot customize an enum's toString method, so I think this helper function workaround is necessary and it's one of the best approaches. If you wanted to be more correct in this case, you could make the first letter of the returned string uppercase.

You could also add a dayFromString function

Day dayFromString(String s) {
  return Day.values.firstWhere((v) => dayToString(v) == s);
}

Example usage:

void main() {
  Day today = Day.monday;
  print('Today is: ${dayToString(today)}');
  Day tomorrow = dayFromString("tuesday");
  print(tomorrow is Day);
}

Solution 15 - Enums

enum day {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);

Solution 16 - Enums

Create a class to help:

class Enum {
    Enum._();

    static String name(value) {
        return value.toString().split('.').last;
    }
}

and call:

Enum.name(myEnumValue);

Solution 17 - Enums

I had the same problem in one of my projects and existing solutions were not very clean and it didn't support advanced features like json serialization/deserialization.

Flutter natively doesn't currently support enum with values, however, I managed to develop a helper package Vnum using class and reflectors implementation to overcome this issue.

Address to the repository:

https://github.com/AmirKamali/Flutter_Vnum

To answer your problem using Vnum, you could implement your code as below:

@VnumDefinition
class Visibility extends Vnum<String> {
  static const VISIBLE = const Visibility.define("VISIBLE");
  static const COLLAPSED = const Visibility.define("COLLAPSED");
  static const HIDDEN = const Visibility.define("HIDDEN");

  const Visibility.define(String fromValue) : super.define(fromValue);
  factory Visibility(String value) => Vnum.fromValue(value,Visibility);
}

You can use it like :

var visibility = Visibility('COLLAPSED');
print(visibility.value);

There's more documentation in the github repo, hope it helps you out.

Solution 18 - Enums

Instead of defining extension for every enum, we can define extension on object and get access to .enumValue from any enum.

void main() {

  // ❌ Without Extension ❌

  print(Countries.Cote_d_Ivoire.toString().split('.').last.replaceAll("_", " ")); // Cote d Ivoire
  print(Movies.Romance.toString().split('.').last.replaceAll("_", " ")); //Romance


  // ✅ With Extension ✅

  print(Countries.Cote_d_Ivoire.enumValue); // Cote d Ivoire
  print(Movies.Romance.enumValue); //Romance
}

enum Countries { United_States, United_Kingdom, Germany, Japan, Cote_d_Ivoire }
enum Movies { Romance, Science_Fiction, Romantic_Comedy, Martial_arts }

extension PrettyEnum on Object {
  String get enumValue => this.toString().split('.').last.replaceAll("_", " ");
}

With this, you can even define multi-word enum where words are separated by _(underscore) in its name.

Solution 19 - Enums

One of the good ways I found in the answer is

String day = theDay.toString().split('.').last;
But I would not suggest doing this as dart provide us a better way.

Define an extension for the enum, may be in the same file as:

enum Day {
  monday, tuesday, wednesday, thursday, friday, saturday, sunday
}

extension DayExtension on Day {
  String get value => describeEnum(this);
}

You need to do import 'package:flutter/foundation.dart'; for this.

Solution 20 - Enums

As from Dart 2.15, you can get enum value from

print(MyEnum.one.name);
// and for getting enum from value you use
print(MyEnum.values.byName('two');

Solution 21 - Enums

As from Dart version 2.15, you can access the String value of an enum constant using .name:

enum day {MONDAY, TUESDAY}

void main() {
  print('Today is ${day.MONDAY.name}');
  // Outputs: Today is MONDAY
}

You can read in detail about all the enum improvements in the official Dart 2.15 release blog post.

Solution 22 - Enums

as of dart 2.15 you can use .name to get the name of enum elements.

enum day {MONDAY, TUESDAY}
print(day.MONDAY.name); // prints MONDAY

Solution 23 - Enums

Dart version 2.15 has introduced name property on enums.

Example

void main() {
  MyEnum.values.forEach((e) => print(e.name));
}

enum MyEnum { value1, Value2, VALUE2 }

Output:

value1
Value2
VALUE2

Solution 24 - Enums

now with null safety it looks like this

String enumToString(Object? o) => o != null ? o.toString().split('.').last : '';


T? enumFromString<T>(String key, List<T> values) {
  try {
    return values.firstWhere((v) => key == enumToString(v));
  } catch(e) {
    return null;
  }
}

Solution 25 - Enums

You can check out this package enum_object

// convert enum value to string
print(TestEnum.test.enumValue);

// convert String to enum value
var enumObject = EnumObject<TestEnum>(TestEnum.values);
print(enumObject.enumFromString('test2'));```

Solution 26 - Enums

try this solution:

extension EnumValueToString on Enum {
  String valueAsString() {
    return describeEnum(this);
  }
}

how to used it:

enum.valueAsString()

Solution 27 - Enums

dart 2.15 is now supporting this you can just type

print(day.MONDAY.name); //gives you: MONDAY

Solution 28 - Enums

Since Dart 2.15, we can just do Day.monday.name, where

enum Day { monday, tuesday }

Solution 29 - Enums

For those who require enum with values use this approach as Dart doesn't support this:

class MyEnumClass {
  static String get KEY_1 => 'value 1';
  static String get KEY_2 => 'value 2';
  static String get KEY_3 => 'value 3';
  ...
}

// Usage:
print(MyEnumClass.KEY_1); // value 1
print(MyEnumClass.KEY_2); // value 2
print(MyEnumClass.KEY_3); // value 3
...

And sure you may put whatever types you need.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNate LockwoodView Question on Stackoverflow
Solution 1 - EnumsmbartnView Answer on Stackoverflow
Solution 2 - EnumsJannie TheunissenView Answer on Stackoverflow
Solution 3 - EnumslrnView Answer on Stackoverflow
Solution 4 - EnumsgbixahueView Answer on Stackoverflow
Solution 5 - EnumsCopsOnRoadView Answer on Stackoverflow
Solution 6 - EnumsDaniel VladcoView Answer on Stackoverflow
Solution 7 - EnumsTimView Answer on Stackoverflow
Solution 8 - EnumsaxumnemonicView Answer on Stackoverflow
Solution 9 - EnumsNaeView Answer on Stackoverflow
Solution 10 - EnumsAlexandr PriezzhevView Answer on Stackoverflow
Solution 11 - EnumsRyan KnellView Answer on Stackoverflow
Solution 12 - EnumsLuckyratView Answer on Stackoverflow
Solution 13 - EnumsKetan ChoyalView Answer on Stackoverflow
Solution 14 - EnumsVince VargaView Answer on Stackoverflow
Solution 15 - EnumsHaroon khanView Answer on Stackoverflow
Solution 16 - EnumsTiagoView Answer on Stackoverflow
Solution 17 - EnumsAmir.n3tView Answer on Stackoverflow
Solution 18 - EnumserluxmanView Answer on Stackoverflow
Solution 19 - EnumsAhmad KhanView Answer on Stackoverflow
Solution 20 - EnumsEdie KamauView Answer on Stackoverflow
Solution 21 - EnumsPéter GyarmatiView Answer on Stackoverflow
Solution 22 - EnumsSinaMN75View Answer on Stackoverflow
Solution 23 - EnumsAbdullah AlsigarView Answer on Stackoverflow
Solution 24 - Enumsmartinseal1987View Answer on Stackoverflow
Solution 25 - EnumsEdie KamauView Answer on Stackoverflow
Solution 26 - EnumsMahmoud Salah EldinView Answer on Stackoverflow
Solution 27 - EnumsAmr AhmedView Answer on Stackoverflow
Solution 28 - EnumskamalbangaView Answer on Stackoverflow
Solution 29 - EnumsOsama RemlawiView Answer on Stackoverflow