Skip to main content

Command Palette

Search for a command to run...

Everything you need to know about Enum with Flutter and Dart

Updated
3 min read
Everything you need to know about Enum with Flutter and Dart
L

I am a mobile software developer specializing in Flutter. I provide quality services to clients. In my journey I worked with 40+ satisfied clients across the world and successfully completed 70+ orders.

Enumerations, often abbreviated by enum, are special class types that allow a limited number of constants to be represented.

Why use an enum rather than a class?

Enum makes it possible to represent a limited number of constants, allowing better readability of the code and easy maintenance.

Using an enum rather than a class depends on the context; if we know all the values in advance it is better to use an enum, otherwise, it is necessary to create a class.

Some examples

User: in this case you have to use a class because there can be an unlimited number of users.

User type: here it is better to use an enum because you should know in advance the user types of your application (e.g.: admin, editor, reader).

Day of the week: we know that there are seven days in the week, so we must use an enum in this case.

Dart enumerations

Dart enumerations are declared and used like in most programming languages.

Statement

In this example, I create a simple day-of-the-week enum with its different values.

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

Use case

WeekDay day = WeekDay.monday;

Advanced options

Problem

Let's return to our example of the Weekday enum, suppose we want to add a number field (monday: 1, tuesday: 2, wednesday: 3, ...) and another representing the short name (monday: “Mon”, tuesday: “Tue ”, wednesday: “Wed”, …); how could we proceed 🤔?

One solution would be to create separate methods that will return the desired values.

Day's number

int getDayNumber(WeekDay day) {
  switch (day) {
    case WeekDay.monday:
      return 1;
    case WeekDay.tuesday:
      return 2;
    case WeekDay.wednesday:
      return 3;
    case WeekDay.thursday:
      return 4;
    case WeekDay.friday:
      return 5;
    case WeekDay.saturday:
      return 6;
    case WeekDay.sunday:
      return 7;
  }
}

Day's short name

String getDayShortName(WeekDay day) {
  switch (day) {
    case WeekDay.monday:
      return 'Mon';
    case WeekDay.tuesday:
      return 'Tue';
    case WeekDay.wednesday:
      return 'Wed';
    case WeekDay.thursday:
      return 'Thu';
    case WeekDay.friday:
      return 'Fri';
    case WeekDay.saturday:
      return 'Sat';
    case WeekDay.sunday:
      return 'Sun';
  }
}

And to call these methods

String day = getDayShortName(WeekDay.monday);
int dayNumber = getDayNumber(WeekDay.monday);

This will work but requires a lot of effort 🏋 and could make maintenance much more difficult anytime we want to add more properties to Weekday.

Solution

Since version 2.17, Dart has improved enumerations by adding the ability to add fields and methods directly to the Enum.

To add a property that represents the number of the day and another that represents the day's short name, we will have:

enum WeekDay {

  monday(1, 'Mon'),
  tuesday(2, 'Tue'),
  wednesday(3, 'Wed'),
  thursday(4, 'Thu'),
  friday(5, 'Fri'),
  saturday(6, 'Sat'),
  sunday(7, 'Sun');

  final int number;
  final String shortName;

  const WeekDay(this.number, this.shortName);

}

All fields must be final and the constructor must be a constant.

We have a much shorter and cleaner code than in our previous method.

For example, we can add a method that returns the WeekDay from the shortName

enum WeekDay {

  monday(1, 'Mon'),
  tuesday(2, 'Tue'),
  wednesday(3, 'Wed'),
  thursday(4, 'Thu'),
  friday(5, 'Fri'),
  saturday(6, 'Sat'),
  sunday(7, 'Sun');

  final int number;
  final String shortName;

  const WeekDay(this.number, this.shortName);

  static WeekDay fromShortName(String shortName) {

    for (final WeekDay weekDay in WeekDay.values) {
      if (weekDay.shortName == shortName) {
        return weekDay;
      }
    }

    throw Exception('Invalid short name: $shortName');
  }

}

This way of doing things offers many possibilities, it is easy to add methods and fields while keeping our code well-structured and organized.

It becomes simple to use its methods and properties:

WeekDay weekDay = WeekDay.fromShortName('Mon');
String day = weekDay.shortName;
int dayNumber = weekDay.number;

Conclusion

There are several ways to achieve your goals in Dart as in other programming languages, but it is important to be able to use the advantages that a programming language offers as much as possible to have clean, well-structured, and therefore easily maintainable code.

In our case, the advanced use of enum allows us a more understandable, clean, and easily maintainable handling.

References

https://dart.dev/language/enums

D

I'm trying to digest Dart right now (coming from C#) and this particular enum thing is more than awesome. I have many ideas to implement your example.

However I'm missing enum flags available in other languages. Turns out there is a library though: https://pub.dev/packages/enum_flag but I think it should be part of the language.

1
L

Thank you Diego for your feedback.

For the moment the enum flag is not natively integrated in Dart, I agree with you, it will be a great option like on C#.

Y

Great information!

We get the ability to add default value if mapping to enum use non-assigned value.

do you have any idea how we can get default value if the enum is nullable? for example:

final WeekDay? weekDay = null;

// I want to get empty string
final String weekDayShortName = weekDay.shortName;

previously, I use something like this:

enum WeekDay {
  monday
}

// extend nullable WeekDay
extension WeekDayExtension on WeekDay? {
  String get shortName {
    switch (this) {
      case WeekDay.monday:
        return 'Mon';
      case null:
        return '';
    }
  }
}
1
L

Thank you for your comment.

If the enum is nullable it can't be used without the null aware operator '?', for me there is not need to add a case for that, you can directly use:

final String weekDayShortName = weekDay?.shortName?? '';

More from this blog

Loïc's blog

9 posts

I am a mobile software developer specializing in Flutter. I provide freelance services in mobile app development.