Open ekuleshov opened 8 months ago
@ekuleshov I faced the same issue. Would it be a good idea to create a .g file for the enum and generate it's enum map there to use it in the rest of the application?
@ekuleshov I faced the same issue. Would it be a good idea to create a .g file for the enum and generate it's enum map there to use it in the rest of the application?
I don't think you can do that without changes in the json_serializable
generator. Currently generated code uses these private const maps in the generated toJson and fromJson implementations.
In any case the model's .dart is the one that is being imported everywhere else, so making these maps globally public and have the generated code in all dependent classes use them instead of generating again should address this.
I had the same problem: a quite big Enum with around 30 values. And its map was copied in every generated code.
Here's a solution, maybe it's not elegant but it works and significantly reduces generation time.
_$ErrorCodeDtoEnumMap
generated in error_code_dto.g.dart
so you don't need to care about it. New values go there.
Now all other models just reuse model's toJson
and fromJson
without duplication.
Enum:
import 'package:json_annotation/json_annotation.dart';
part 'error_code_dto.g.dart';
@JsonEnum(alwaysCreate: true)
enum ErrorCodeDto {
@JsonValue('CredentialsInvalid')
credentialsInvalid,
/// many other values ...
@JsonValue('ValidationError')
validationError,
@JsonValue('Unknown')
unknown;
factory ErrorCodeDto.fromJson(dynamic value) =>
$enumDecodeNullable(
_$ErrorCodeDtoEnumMap,
value,
unknownValue: ErrorCodeDto.unknown,
) ??
ErrorCodeDto.unknown;
String? toJson() =>
_$ErrorCodeDtoEnumMap[this] ??
_$ErrorCodeDtoEnumMap[ErrorCodeDto.unknown];
}
Example of generated model:
CommonResponse _$CommonResponseFromJson(Map<String, dynamic> json) =>
CommonResponse(
success: json['success'] as bool,
message: json['message'] as String?,
errorCode: json['errorCode'] == null
? null
: ErrorCodeDto.fromJson(json['errorCode']),
);
I had the same problem: a quite big Enum with around 30 values. And its map was copied in every generated code.
Here's a solution, maybe it's not elegant but it works and significantly reduces generation time.
Of course. But that is quite a bit of manually written boiler plate code that could be generated. Also, this won't work when you have a 3rd party model from another module.
When
json_serializable
is generating code to serialize anenum
values it creates a private const map named_$<enum name>EnumMap
.However this map is being generated not for the dart source file where this enum is declared at, but in the sources this enum is referenced in. Basically the same map is generated for every source file that is referencing that same
enum
type.This adds some code duplication even when this enum is serialized the same way in all places.
Additionally, if the model where this enum is declared at is coming from a different module (e.g. a common data model or some common API) we have to regenerate all generated code in all modules that depend on the module where enum is coming from.
To address those two issues it would be great if
json_serializable
could generate a public map or a common public method that would be used from the generated code that serializes enum value in all other places.Using: