Dart json_serializable defaultValue для карты со значением Enum
Моя основная проблема заключается в том, что я хочу, чтобы значение поля не получило нулевое значение при создании объекта из синтаксического анализа json. Поле представляет собой Map
Пример кода:
import 'package:json_annotation/json_annotation.dart';
enum Letter{ A, B,C}
@JsonSerializable()
class example{
@JsonKey(defaultValue: {
'C': Letter.C
})
Map<String, Letter> letters = {
'A': Letter.A,
'B':Letter.B
};
}
Ошибка возникает при запуске:
flutter pub run build_runner build
Сообщение об ошибке:
Ошибка запуска JsonSerializableGenerator Ошибка с
@JsonKey
наletters
.defaultValue
являетсяMap > Letter
, это должно быть буквальное значение.
Нашел это:https://github.com/google/json_serializable.dart/issues/361
Но если я попытаюсь использовать методы конвертера, я столкнусь с другими проблемами, поэтому попытаюсь решить основную проблему.
2 ответа
Используйте свойство name и метод перечислений byName
import 'dart:convert';
void main() {
Person raj = Person(name: 'Raj', favIcecream: Icecream.pista);
print(raj.toJson());
Person rajV2 = Person.fromJson(raj.toJson());
print(rajV2.toJson());
final isBothInstanceEqual = raj == rajV2;
print('> Both instancecs are equal is $isBothInstanceEqual');
}
enum Icecream {
vanilla,
pista,
strawberry,
}
class Person {
String name;
Icecream favIcecream;
Person({
required this.name,
required this.favIcecream,
});
Map<String, dynamic> toMap() {
return {
'name': name,
'favIcecream': favIcecream.name, // <- this is how you should save
};
}
factory Person.fromMap(Map<String, dynamic> map) {
return Person(
name: map['name'] ?? '',
favIcecream: Icecream.values.byName(map['favIcecream']), // <- back to enum
);
}
String toJson() => json.encode(toMap());
factory Person.fromJson(String source) => Person.fromMap(json.decode(source));
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Person &&
other.name == name &&
other.favIcecream == favIcecream;
}
@override
int get hashCode => name.hashCode ^ favIcecream.hashCode;
}
Решение, работающее в минимальном масштабе.
pupspec.yaml:
name: playground
description: A simple command-line application.
environment:
sdk: '>=2.8.1 <3.0.0'
dependencies:
json_annotation: ^3.0.1
dev_dependencies:
build_runner: ^1.10.0
json_serializable: ^3.3.0
pedantic: ^1.9.0
игровая площадка.dart:
import 'package:json_annotation/json_annotation.dart';
part 'playground.g.dart';
enum Letter{ A, B, C}
@JsonSerializable()
class example{
example(){}
@JsonKey(fromJson: parseMap, toJson: toStringMap)
Map<String, Letter> letters = {
'A': Letter.A,
'B':Letter.B
};
factory example.fromJson(Map<String, dynamic> json) => _$exampleFromJson(json);
Map<String, dynamic> toJson() => _$exampleToJson(this);
static Map<String, Letter> parseMap(Map<String,String> m){
if(m==null){
return {
'C': Letter.C
};
}
Map<String, Letter> result ={};
for(String key in m.keys){
result[key]=Letter.values.firstWhere((e) => e.toString() == m[key]);
}
return result;
}
static Map<String, String> toStringMap(Map<String,Letter> m){
if(m==null){
return {
'C': 'C'
};
}
Map<String, String> result ={};
for(String key in m.keys){
result[key]=m[key].toString();
}
return result;
}
}
void main(List<String> arguments) {
var ex = example.fromJson({});
print(ex.letters.values);
var ex2 = new example();
var m =ex2.toJson();
print(m);
var ex3 = new example();
ex3.letters=null;
var m2 =ex3.toJson();
print(m2);
}
Бегать:
pub run build_runner build
dart .\bin\playground.dart
Выход:
(Буква.C)
{письма: {A: Буква.A, B: Буква.B}}
{буквы: {C: C}}