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 value of the enum as
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.
I use structure like below:
class Strings {
static const angry = "Dammit!";
static const happy = "Yay!";
static const sad = "QQ";
}
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.
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.
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);
}
Bit shorter:
String day = theDay.toString().split('.').last;