google / google/json_serializable.dart

enum as Map keys causing key type is int

Open
#1,362 13 comments 0 reactions 0 assignees View on GitHub
Type: enhancement
Dominant language
Dart
Stars
1.6k
Forks
461
Avg merge
45m
Merged PRs (30d)
1

Description

## Problem
```dart
@JsonSerializable()
class MyClass {
final Map inv;

MyClass({required this.inv});

factory MyClass.fromJson(Map json) =>
_$MyClassFromJson(json);

Map toJson() => _$MyClassToJson(this);
}

enum Slot {
@JsonValue(1)
slot1,
@JsonValue(2)
slot2,
@JsonValue('3')
slot3,
}
```
generated enum map
```dart
const _$SlotEnumMap = {
Slot.slot1: 1,
Slot.slot2: 2,
Slot.slot3: '3',
};
```

Generated toJson:
```dart
instance.inv.map((k, e) => MapEntry(_$SlotEnumMap[k]!, e))
```

Since enums can be Map keys, and enums can be tranfered to int with JsonValue.
This produces a out come that the json key is a int.

Generated fromJson:
```dart
(json['inv'] as Map).map(
(k, e) => MapEntry($enumDecode(_$SlotEnumMap, k), e as String),
)
```

I don't think this should happen, since json's key should always be a String.

## A solution would be:

Generated toJson:
```dart
instance.inv.map((k, e) => MapEntry(_$SlotEnumMap[k]!.toString(), e)) //added toString()
```

Generated fromJson:
```dart
(json['inv'] as Map).map(
(k, e) => MapEntry($enumDecodeJsonKey(_$SlotEnumMap, k), e as String), //uses a different decode function.
)
```
enumDecodeJsonKey would be a helper specific for enum map keys, would have something like.
```dart
for (var entry in enumValues.entries) {
if (entry.value == source || entry.value.toString() == entry.value) {
return entry.key;
}
}
```

**If this looks nice , I'd be happy to work on this and submit a pr!**

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.