Freezed и json_serializable: как использовать собственный конвертер
Я хочу добавить собственный конвертер в замороженный класс, как в этом ответе .
Я пробовал это с помощью этого кода:
@freezed
class NewsPost with _$NewsPost {
factory NewsPost({
@JsonKey(name: "date") @TimestampConverter() DateTime? date,
}) = _NewsPost;
factory NewsPost.fromJson(Map<String, dynamic> json) =>
_$NewsPostFromJson(json);
}
Но не вышло. Любые идеи приветствуются!
Для вашего интереса это мой конвертер:
class TimestampConverter implements JsonConverter<DateTime, Timestamp> {
const TimestampConverter();
@override
DateTime fromJson(Timestamp timestamp) {
return timestamp.toDate();
}
@override
Timestamp toJson(DateTime date) => Timestamp.fromDate(date);
}
Спасибо :-)
2 ответа
Поскольку была введена нулевая безопасность, для работы с генератором допускаемость значений NULL для типов, объявленных в
JsonConverter
необходимо сопоставить допустимость значения NULL для типа в замороженном классе.
Если типы не совпадают,
freezed
игнорирует преобразователь.
Итак, используя ваш пример:
@freezed
class NewsPost with _$NewsPost {
factory NewsPost({
@TimestampOrNullConverter() DateTime? date, // <-- this is nullable, so the converter needs to handle null
@TimestampConverter() DateTime createdAt, // <-- not nullable, so your exsiting converter will work
}) = _NewsPost;
factory NewsPost.fromJson(Map<String, dynamic> json) =>
_$NewsPostFromJson(json);
}
class TimestampConverter implements JsonConverter<DateTime, Timestamp> {
const TimestampConverter();
@override
DateTime fromJson(Timestamp timestamp) {
return timestamp.toDate();
}
@override
Timestamp toJson(DateTime date) => Timestamp.fromDate(date);
}
class TimestampOrNullConverter implements JsonConverter<DateTime?, Timestamp?> {
const TimestampConverter();
@override
DateTime? fromJson(Timestamp? timestamp) {
return timestamp?.toDate();
}
@override
Timestamp? toJson(DateTime? date) => date == null ? null : Timestamp.fromDate(date);
}
Протестировано и работает над flutter 2.5.3 со следующими версиями зависимостей:
dev_dependencies:
build_runner: ^2.1.4
freezed: ^0.15.0+1
json_serializable: ^5.0.2
Что ж, это не самое элегантное решение, но оно работает.
@freezed
class NewsPost with _$NewsPost {
factory NewsPost({
@JsonKey(
name: "date",
fromJson: dateTimeFromJson,
fromJson: dateTimeToJson,
) DateTime? date,
}) = _NewsPost;
factory NewsPost.fromJson(Map<String, dynamic> json) =>
_$NewsPostFromJson(json);
}
DateTime dateTimeFromJson(Timestamp timestamp) {
return timestamp.toDate();
}
Timestamp dateTimeToJson(DateTime date) => Timestamp.fromDate(date);
Думаю, это выход. Используя JsonConverter, я не могу заставить его работать.