具有枚举值的映射的 Dart json_serializable defaultValue
Posted
技术标签:
【中文标题】具有枚举值的映射的 Dart json_serializable defaultValue【英文标题】:Dart json_serializable defaultValue for Map with Enum Value 【发布时间】:2020-10-15 05:56:39 【问题描述】:我的主要问题是我想在通过解析 json 创建对象时防止字段值变为 null。
该字段是一个 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
onletters
。defaultValue
是Map > Letter
,必须是字面量。
发现这个: https://github.com/google/json_serializable.dart/issues/361
但是如果我尝试使用转换器方法,我会遇到其他问题,因此尝试解决根本问题。
【问题讨论】:
【参考方案1】:使用枚举的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;
【讨论】:
【参考方案2】:适用于最小规模的解决方案。
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
playground.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:Letter.A,B:Letter.B 字母:C:C
【讨论】:
以上是关于具有枚举值的映射的 Dart json_serializable defaultValue的主要内容,如果未能解决你的问题,请参考以下文章