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?
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'
}
Bit shorter:
String day = theDay.toString().split('.').last;
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'
}
It used to be correct that the only way to get the source name
of the enum value was through the toString method which returns "day.MONDAY", and not the more useful "MONDAY".
Since Dart 2.15, enums have exposed a extension getter which returns just the source name, so day.MONDAY.name == "MONDAY".
Since Dart 2.17, you can also add your own members to enum declarations, and choose to provide another name for
a value than justits source name, e.g., with a more appropriate capitalization:
enum Day {
monday("Monday"),
tuesday("Tuesday"),
// ...
saturday("Saturday");
sunday("Sunday");
final String name;
Day(this.name);
// And other members too.
bool get isWorkday => index < saturday.index;
}
Then you get Day.sunday.name == "Sunday" (hiding the extension name getter which would return "sunday").
Before these features, you could only get the name from the toString string, extracting the rest of the string as:
day theDay = day.MONDAY;
print(theDay.toString().substring(theDay.toString().indexOf('.') + 1));
which was admittedly hardly convenient.
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, was:
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);
}
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');
}
enum day {MONDAY, TUESDAY}
print( 'Today is ${describeEnum(day.MONDAY)}' );
console output: Today is MONDAY
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"
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
With Dart 2.17 we now have general support for members on enums. That means we can add fields holding state, constructors that set that state, methods with functionality, and even override existing members.
Example:
enum Day {
MONDAY("Monday"),
TUESDAY("Tuesday");
const Day(this.text);
final String text;
}
Output:
void main() {
const day = Day.MONDAY;
print(day.text); /// Monday
}
For above functionality override dart version like below which target 2.17 and greater
environment:
sdk: ">=2.17.0 <3.0.0"
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.
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 use structure like below:
abstract class Strings {
static const angry = "Dammit!";
static const happy = "Yay!";
static const sad = "QQ";
}
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.
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];
}
since dart 2.15 just use ".name"
enum day {monday, tuesday}
print( 'Today is ${day.monday.name}');
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);
}
enum day {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);
Create a class to help:
class Enum {
Enum._();
static String name(value) {
return value.toString().split('.').last;
}
}
and call:
Enum.name(myEnumValue);
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.
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.
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.
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');
try this solution:
extension EnumValueToString on Enum {
String valueAsString() {
return describeEnum(this);
}
}
how to used it:
enum.valueAsString()
dart 2.15 is now supporting this
you can just type
print(day.MONDAY.name); //gives you: MONDAY
Since Dart 2.15, we can just do Day.monday.name, where
enum Day { monday, tuesday }
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.
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
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
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.
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;
}
}
Related
I have a typescript enum that looks like this:
enum State {
NotRequired,
Working,
PendingReview,
Reviewed,
Done
}
And this generates this:
var State;
(function (State) {
State[State["NotRequired"] = 0] = "NotRequired";
State[State["Working"] = 1] = "Working";
State[State["PendingReview"] = 2] = "PendingReview";
State[State["Reviewed"] = 3] = "Reviewed";
State[State["Done"] = 4] = "Done";
})(State || (State = {}));
I would like to have the values a nicely formed string with spaces where required.
So State[State["PendingReview"] = 2] = "PendingReview"; would become State[State["PendingReview"] = 2] = "Pending Review";
I have managed to achieve something close to this by defining my enum like so:
enum State {
"Not Required",
Working,
"Pending Review",
Reviewed,
Done
}
However this has the drawback that to use any enum value in code with a space i now have to use my key instead.
So State.PendingReview now has to be used like this State["Pending Review"]
Can i have the best of both worlds by somehow defining an alternative display string to my key?
So that when i say State[State.PendingReview] it gives me the value "Pending Review"
As you're not specifying explicit values for the enum, you may as well use a string enum (available as of TypeScript 2.4) for this:
enum State {
NotRequired = "Not Required",
Working = "Working",
PendingReview = "Pending Review",
Reviewed = "Reviewed",
Done = "Done"
}
The display value then simply becomes e.g. State.NotRequired.
Since enums does not supports string values,
would be better to use a class with static fields like this.
You have the compilation checks like if you where using enum, you call it the same way in your code also.
module rizze.tests {
enum State{
NotRequiered,
Working,
Pending,
Reviewed,
Done
}
class StateConvert {
static NotRequiered="Not Required";
static Working="I'm Working";
static Pending = "Pending Review";
static Reviewed="Reviewed Done";
static Done="Done All";
static convert(state:State):String{
if( state == null) return null;
switch(state){
case State.NotRequiered:{return StateConvert.NotRequiered;}
case State.Working:{return StateConvert.Working;}
case State.Pending:{return StateConvert.Pending;}
case State.Reviewed:{return StateConvert.Reviewed;}
case State.Done:{return StateConvert.Done;}
}
console.log("Error state undefined + " +state );
return null;
}
}
export class StateTest {
constructor(){
let state:State = State.Reviewed;
console.log("state:"+state + " / " + StateConvert.convert(state));
}
}
//TEST
let s:StateTest= new StateTest();
}
Can i have the best of both worlds by somehow defining an alternative
display string to my key?
No. This is not supported in TypeScript. You could try to make a feature request if you think this would be valuable.
Is there a way to convert a string to an enum?
enum eCommand{fred, joe, harry}
eCommand theCommand= cast(eCommand, 'joe');??
I think I just have to search for the enum (eg loop).
cheers
Steve
I got annoyed with the state of enums and built a library to handle this:
https://pub.dev/packages/enum_to_string
Basic usage:
import 'package:enum_to_string:enum_to_string.dart';
enum TestEnum { testValue1 };
main(){
final result = EnumToString.fromString(TestEnum.values, "testValue1");
// TestEnum.testValue1
}
Still more verbose than I would like, but gets the job done.
I have came up with a solution inspired from https://pub.dev/packages/enum_to_string that can be used as a simple extension on List
extension EnumTransform on List {
String string<T>(T value) {
if (value == null || (isEmpty)) return null;
var occurence = singleWhere(
(enumItem) => enumItem.toString() == value.toString(),
orElse: () => null);
if (occurence == null) return null;
return occurence.toString().split('.').last;
}
T enumFromString<T>(String value) {
return firstWhere((type) => type.toString().split('.').last == value,
orElse: () => null);
}
}
Usage
enum enum Color {
red,
green,
blue,
}
var colorEnum = Color.values.enumFromString('red');
var colorString: Color.values.string(Color.red)
Dart 2.6 introduces methods on enum types. It's much better to call a getter on the Topic or String itself to get the corresponding conversion via a named extension. I prefer this technique because I don't need to import a new package, saving memory and solving the problem with OOP.
I also get a compiler warning when I update the enum with more cases when I don't use default, since I am not handling the switch exhaustively.
Here's an example of that:
enum Topic { none, computing, general }
extension TopicString on String {
Topic get topic {
switch (this) {
case 'computing':
return Topic.computing;
case 'general':
return Topic.general;
case 'none':
return Topic.none;
}
}
}
extension TopicExtension on Topic {
String get string {
switch (this) {
case Topic.computing:
return 'computing';
case Topic.general:
return 'general';
case Topic.none:
return 'none';
}
}
}
This is really easy to use and understand, since I don't create any extra classes for conversion:
var topic = Topic.none;
final string = topic.string;
topic = string.topic;
(-:
As of Dart 2.15, you can use the name property and the byName() method:
enum eCommand { fred, joe, harry }
eCommand comm = eCommand.fred;
assert(comm.name == "fred");
assert(eCommand.values.byName("fred") == comm);
Just be aware that the byName method throws an ArgumentError if the string is not recognized as a valid member in the enumeration.
For the Dart enum this is a bit cumbersome.
See Enum from String for a solution.
If you need more than the most basic features of an enum it's usually better to use old-style enums - a class with const members.
See How can I build an enum with Dart? for old-style enums
This is the fastest way I found to do this :
enum Vegetable { EGGPLANT, CARROT, TOMATO }
Vegetable _getVegetableEnum(dynamic myVegetableObject) {
return Vegetable.values.firstWhere((e) => describeEnum(e) == myVegetableObject);
}
i had the same problem, a small enum and a string, so i did this
dynamic _enum_value = EnumFromString(MyEnum.values, string_to_enum);
dynamic EnumFromString(List values, String comp){
dynamic enumValue = null;
values.forEach((item) {
if(item.toString() == comp){
enumValue = item;
}
});
return enumValue;
}
i know this is not the best solution, but it works.
Static extension methods would make this nice (currently unimplemented).
Then you could have something like this:
extension Value on Keyword {
/// Returns the valid string representation of a [Keyword].
String value() => toString().replaceFirst(r'Keyword.$', '');
/// Returns a [Keyword] for a valid string representation, such as "if" or "class".
static Keyword toEnum(String asString) =>
Keyword.values.firstWhere((kw) => kw.value() == asString);
}
FOUND ANS
Check this article. Very well explained: Link
extension EnumParser on String {
T toEnum<T>(List<T> values) {
return values.firstWhere(
(e) => e.toString().toLowerCase().split(".").last ==
'$this'.toLowerCase(),
orElse: () => null,
),
}
}
The cleanest way is to use built-in functionality:
enum EmailStatus {
accepted,
rejected,
delivered,
failed,
}
EmailStatus.values.byName('failed') == EmailStatus.failed;
=> true
Is there a way to use enum default parameters in Haxe? I get this error:
Parameter default value should be constant
enum AnEnum {
A;
B;
C;
}
class Test {
static function main() {
Test.enumNotWorking();
}
static function enumNotWorking(e:AnEnum = AnEnum.A){}
}
Try Haxe link.
Update: this feature has been added in Haxe 4. The code example from the question now compiles as-is with a regular enum.
Previously, this was only possible if you're willing to use enum abstracts (enums at compile time, but a different type at runtime):
#:enum
abstract AnEnum(Int)
{
var A = 1;
var B = 2;
var C = 3;
}
class Test3
{
static function main()
{
nowItWorks();
}
static function nowItWorks(param = AnEnum.A)
{
trace(param);
}
}
There's nothing special about the values I chose, and you could choose another type (string, or a more complex type) if it better suits your use case. You can treat these just like regular enums (for switch statements, etc.) but note that when you trace it at runtime, you'll get "1", not "A".
More information: http://haxe.org/manual/types-abstract-enum.html
Sadly enums can't be used as default values, because in Haxe enums aren't always constant.
This piece of trivia was on the old website but apparently hasn't made it into the new manual yet:
http://old.haxe.org/ref/enums#using-enums-as-default-value-for-parameters
The workaround is to check for a null value at the start of your function:
static function enumNotWorking(?e:AnEnum){
if (e==null) e=AnEnum.A;
}
Alternatively, an Enum Abstract might work for your case.
I would like to define an enum-like structure in JS, but have two requirements:
The values be read-only, i.e. no users can assign to them.
The values (0, 1, 2, ...) can be mapped back into the names (as with Java's name method)
The methods I know to create enums like this typically meet one requirement or the other, not both.
I've tried:
const MyEnum = {
a: 0,
b: 1,
c: 2
};
The enum itself is constant, but the values are still mutable and I can't map values back to names efficiently.
When writing an enum in Typescript, it outputs:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["a"] = 0] = "a";
MyEnum[MyEnum["b"] = 1] = "b";
MyEnum[MyEnum["c"] = 2] = "c";
})(MyEnum || (MyEnum = {}));
This can map both ways, but still doesn't have constant values.
The only option I've found that meets both requirements would be using getters on a class:
class MyEnum {
get a() {
return 0;
}
...
}
This method dramatically restricts the legal names and has a lot of overhead, especially in browsers that don't inline getters well (or can't).
#Shmiddty suggested freezing an object:
const MyEnum = Object.freeze({
a: 0,
b: 1,
c: 2
});
This meets the constant requirement well, but doesn't provide a great way to map values back to names.
I could write a helper that builds the reverse mapping like:
function reverseEnum(enum) {
Object.keys(enum).forEach(k => {
enum[enum[k]] = k;
});
}
But any kind of programmatic solution to generate the reverse mapping will run into problems if the original object is frozen or otherwise actually constant.
Is there a clean, concise solution to this in JS?
This does a pretty good job, IMHO.
function Enum(a){
let i = Object
.keys(a)
.reduce((o,k)=>(o[a[k]]=k,o),{});
return Object.freeze(
Object.keys(a).reduce(
(o,k)=>(o[k]=a[k],o), v=>i[v]
)
);
} // y u so terse?
const FOO = Enum({
a: 0,
b: 1,
c: "banana"
});
console.log(FOO.a, FOO.b, FOO.c); // 0 1 banana
console.log(FOO(0), FOO(1), FOO("banana")); // a b c
try {
FOO.a = "nope";
}
catch (e){
console.log(e);
}
I'd use a Map so that your enum values can be any type, rather than having them coerced into strings.
function Enum(obj){
const keysByValue = new Map();
const EnumLookup = value => keysByValue.get(value);
for (const key of Object.keys(obj)){
EnumLookup[key] = obj[key];
keysByValue.set(EnumLookup[key], key);
}
// Return a function with all your enum properties attached.
// Calling the function with the value will return the key.
return Object.freeze(EnumLookup);
}
If your enum is all strings, I'd also probably change one line to:
EnumLookup[key] = Symbol(obj[key]);
to ensure that the enum values are being used properly. Using just a string, you have no guarantee that some code hasn't simply passed a normal string that happens to be the same as one of your enum values. If your values are always strings or symbols, you could also swap out the Map for a simple object.
Just recently implemented an Es6 version that works quite well:
const k_VALUES = {}
export class ErrorCode {
constructor(p_apiCode, p_httpCode){
this.apiCode = p_apiCode;
this.httpCode = p_httpCode;
k_VALUES[p_apiCode] = this;
}
static create(p_apiCode){
if(k_VALUES[p_apiCode]){
return k_VALUES[p_apiCode];
}
return ErrorCode.UNKNOWN;
}
}
ErrorCode.UNKNOWN = new ErrorCode(0, 500);
ErrorCode.NOT_FOUND = new ErrorCode(-1000, 404);
ErrorCode.NOT_FOUND_EMAIL = new ErrorCode(-1001, 404);
ErrorCode.BAD_REQUEST = new ErrorCode(-1010, 404);
I wanted to implement a similar pattern as what we do with Java enums. This enables me to use a constructor to pass values. The constructor then freezes the ErrorCode object - nice and convenient.
Usage: first import your enum class...
import {ErrorCode} from "../common/services/errors/ErrorCode";
Now, after importing the enum class, access it like so:
if( errCode.includes(ErrorCode.BAD_REQUEST.apiCode) ){...}
PS> This is used in conjunction with a Webpack setup using Babel to convert our ES6 classes down for browser compatibility.
Does Dart support enumerations? For instance:
enum myFruitEnum { Apple, Banana }
A cursory search of the docs suggests no.
Beginning 1.8, you can use enums like this:
enum Fruit {
apple, banana
}
main() {
var a = Fruit.apple;
switch (a) {
case Fruit.apple:
print('it is an apple');
break;
}
// get all the values of the enums
for (List<Fruit> value in Fruit.values) {
print(value);
}
// get the second value
print(Fruit.values[1]);
}
The old approach before 1.8:
class Fruit {
static const APPLE = const Fruit._(0);
static const BANANA = const Fruit._(1);
static get values => [APPLE, BANANA];
final int value;
const Fruit._(this.value);
}
Those static constants within the class are compile time constants, and this class can now be used in, for example, switch statements:
var a = Fruit.APPLE;
switch (a) {
case Fruit.APPLE:
print('Yes!');
break;
}
With r41815 Dart got native Enum support see http://dartbug.com/21416 and can be used like
enum Status {
none,
running,
stopped,
paused
}
void main() {
print(Status.values);
Status.values.forEach((v) => print('value: $v, index: ${v.index}'));
print('running: ${Status.running}, ${Status.running.index}');
print('running index: ${Status.values[1]}');
}
[Status.none, Status.running, Status.stopped, Status.paused]
value: Status.none, index: 0
value: Status.running, index: 1
value: Status.stopped, index: 2
value: Status.paused, index: 3
running: Status.running, 1
running index: Status.running
A limitation is that it is not possibly to set custom values for an enum item, they are automatically numbered.
More details at in this draft https://www.dartlang.org/docs/spec/EnumsTC52draft.pdf
Enumeration should be available in the future. But until Enum has landed you can do something like :
class Fruit {
static final APPLE = new Fruit._();
static final BANANA = new Fruit._();
static get values => [APPLE, BANANA];
Fruit._();
}
This and this may be the answers on your question:
... for the technology preview it was decided to leave it out and just
use static final fields for now. It may be added later.
You can still do something like this:
interface ConnectionState { }
class Connected implements ConnectionState { }
class Connecting implements ConnectionState { }
class Disconnected implements ConnectionState { }
//later
ConnectionState connectionState;
if (connectionState is Connecting) { ... }
wich is in my opinion more clear for use. It's a bit more difficult for programming the application structure, but in some cases, it's better and clear.
how about this approach:
class FruitEnums {
static const String Apple = "Apple";
static const String Banana = "Banana";
}
class EnumUsageExample {
void DoSomething(){
var fruit = FruitEnums.Apple;
String message;
switch(fruit){
case(FruitEnums.Apple):
message = "Now slicing $fruit.";
break;
default:
message = "Now slicing $fruit via default case.";
break;
}
}
}
Yes! Its actually very useful to do Enums in Dart:
enum fruits{
BANANA, APPLE, ORANGE
}
Just use Types Class File.
Dart-Types
easy, fast, more powerful and more helpful.
little problem, it is this class limited to five Different Choice and plus one for acts as null.
In case of anybody still searching for a quick solution for this.
We sometimes need integer value for an enum , sometimes string value. So we implement a quick package for this.
Enum Value Generator and an extension to easly generate necessary codes but this is not mandatory.vscode extension.
It is also capable of use with jsonAnnotation too.
import 'package:mobkit_generator/annotations.dart';
part 'example.g.dart'
#EnumSerializable(String)
enum PersonStr {
#EnumValue('John')
name,
#EnumValue('66')
number,
}
#EnumSerializable(int)
enum PersonInt {
#EnumValue(1)
name,
#EnumValue('66')
number,
}