Freezed: Converting strings to enums & generating string lists

Created on 3 Jun 2020  路  3Comments  路  Source: rrousselGit/freezed

@freezed
abstract class SomeEnum implements _$SomeEnum {
  const SomeEnum._();
  const factory SomeEnum(String label) = _SomeEnum;
  static const enum1 = SomeEnum("enum1");
  static const enum2 = SomeEnum("enum2");
  static const enum3 = SomeEnum("enum3");
  factory SomeEnum.fromJson(String val) => SomeEnum(val);

  @override
  String toString() => this.label;

  static List<String> toStringList() {
    return [enum1.toString(), enum2.toString(), enum3.toString()]
  }

  static dynamic stringToEnum(String val) {
    if (val == enum1.toString()) return enum1;
    if (val == enum2.toString()) return enum2;
    if (val == enum3.toString()) return enum3;
    return null;
  }
}

Is there a way to have the stringToEnum() and toStringList() methods auto-generated?

Most helpful comment

Just as additional info:

You can use a normal enum inside @freezed classes
(this only works, if for your specific use-case it is not required that the enum is its own freezed class)

// todo.dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'todo.freezed.dart';
part 'todo.g.dart';

enum Status {
  @JsonValue('OPEN') open,
  @JsonValue('PROGRESS') inProgress,
  @JsonValue('REVIEW') review,
  @JsonValue('DONE') done,
}

@freezed
abstract class Todo with _$Todo {
  factory Todo(String name, Status status) = _Todo;
  factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
}

Additionally you can write this extension on your enum:

extension StatusUtil on Status {
  String enumToString() => _$StatusEnumMap[this];
  static Status stringToEnum(String value) => _$enumDecodeNullable(_$StatusEnumMap, value);
  static List<String> toStringList() => _$StatusEnumMap.values.toList();
}

Then

// main.dart
import 'todo.dart';

void main() {
  final jsonMap = Todo('Some Todo', Status.open).toJson();
  final todo = Todo.fromJson({'name': 'Other Todo', 'status': 'PROGRESS'});
  print(jsonMap); /// {name: Some Todo, status: OPEN}
  print(todo); /// Todo(name: Other Todo, status: Status.inProgress)
  print(StatusUtil.toStringList()); /// [OPEN, PROGRESS, REVIEW, DONE]
}

All 3 comments

Enums currently do not have proper support.

Just as additional info:

You can use a normal enum inside @freezed classes
(this only works, if for your specific use-case it is not required that the enum is its own freezed class)

// todo.dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'todo.freezed.dart';
part 'todo.g.dart';

enum Status {
  @JsonValue('OPEN') open,
  @JsonValue('PROGRESS') inProgress,
  @JsonValue('REVIEW') review,
  @JsonValue('DONE') done,
}

@freezed
abstract class Todo with _$Todo {
  factory Todo(String name, Status status) = _Todo;
  factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
}

Additionally you can write this extension on your enum:

extension StatusUtil on Status {
  String enumToString() => _$StatusEnumMap[this];
  static Status stringToEnum(String value) => _$enumDecodeNullable(_$StatusEnumMap, value);
  static List<String> toStringList() => _$StatusEnumMap.values.toList();
}

Then

// main.dart
import 'todo.dart';

void main() {
  final jsonMap = Todo('Some Todo', Status.open).toJson();
  final todo = Todo.fromJson({'name': 'Other Todo', 'status': 'PROGRESS'});
  print(jsonMap); /// {name: Some Todo, status: OPEN}
  print(todo); /// Todo(name: Other Todo, status: Status.inProgress)
  print(StatusUtil.toStringList()); /// [OPEN, PROGRESS, REVIEW, DONE]
}

I'll close this in favor of #74

Was this page helpful?
0 / 5 - 0 ratings