JsonSerializable。无法将模型与 json 架构匹配
JsonSerializable. Can't match Model to json schema
以下 json 是 Google Place Details Api.
请求的响应正文
{
"html_attributions": [],
"result": {
"address_components": [
{
"long_name": "18",
"short_name": "18",
"types": [
"street_number"
]
},
{
"long_name": "Doiranis",
"short_name": "Doiranis",
"types": [
"route"
]
},
{
"long_name": "Thessaloniki",
"short_name": "Thessaloniki",
"types": [
"locality",
"political"
]
},
{
"long_name": "Thessaloniki",
"short_name": "Thessaloniki",
"types": [
"administrative_area_level_3",
"political"
]
},
{
"long_name": "Greece",
"short_name": "GR",
"types": [
"country",
"political"
]
},
{
"long_name": "546 39",
"short_name": "546 39",
"types": [
"postal_code"
]
}
]
},
"status": "OK"
}
下面是我的Place
模型class
import 'package:json_annotation/json_annotation.dart';
part 'place_model.g.dart';
@JsonSerializable(fieldRename: FieldRename.snake)
class Place {
final String streetName;
final String streetNumber;
final String city;
final String zipCode;
Place({
required this.streetName,
required this.streetNumber,
required this.city,
required this.zipCode,
});
factory Place.fromJson(Map<String, dynamic> json) => _$PlaceFromJson(json);
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'place_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Place _$PlaceFromJson(Map<String, dynamic> json) => Place(
streetName: json['street_name'] as String,
streetNumber: json['street_number'] as String,
city: json['city'] as String,
zipCode: json['zip_code'] as String,
);
Map<String, dynamic> _$PlaceToJson(Place instance) => <String, dynamic>{
'street_name': instance.streetName,
'street_number': instance.streetNumber,
'city': instance.city,
'zip_code': instance.zipCode,
};
我的 Place
模型需要 address_components
列表中的 short_name
值,但是
目前我的模型与 json 架构不匹配。
我是一个没有经验的开发人员,这可能很简单。但是你能建议我一种正确生成 place_model.g.dart
的方法吗?
响应与您的目标不匹配class,因此您必须先转换它。
为响应创建模型:
@JsonSerializable()
class Response {
final Result result;
final String status;
const Response({required this.result, required this.status});
factory Response.fromJson(Map<String, dynamic> json) =>
_$ResponseFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class Result {
final List<AddressComponents> addressComponents;
const Result({required this.addressComponents});
factory Result.fromJson(Map<String, dynamic> json) => _$ResultFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class AddressComponents {
final String longName;
final String shortName;
final List<String> types;
const AddressComponents({
required this.longName,
required this.shortName,
required this.types,
});
factory AddressComponents.fromJson(Map<String, dynamic> json) =>
_$AddressComponentsFromJson(json);
}
现在您可以向 Place
模型添加一个工厂构造函数,它将从 Response
:
构建一个 Place
模型
class Place {
const Place({
this.streetName,
this.streetNumber,
this.city,
this.zipCode,
});
final String? streetName;
final String? streetNumber;
final String? city;
final String? zipCode;
factory Place.fromResponse(Response response) {
final streetNumberComponent = response.result.addressComponents
.where((c) => c.types.contains('street_number'));
// .. here the rest of Place fields
return Place(
streetNumber: streetNumberComponent.isNotEmpty
? streetNumberComponent.first.shortName
: null,
// .. here the rest of Place fields
);
}
}
以下 json 是 Google Place Details Api.
请求的响应正文{
"html_attributions": [],
"result": {
"address_components": [
{
"long_name": "18",
"short_name": "18",
"types": [
"street_number"
]
},
{
"long_name": "Doiranis",
"short_name": "Doiranis",
"types": [
"route"
]
},
{
"long_name": "Thessaloniki",
"short_name": "Thessaloniki",
"types": [
"locality",
"political"
]
},
{
"long_name": "Thessaloniki",
"short_name": "Thessaloniki",
"types": [
"administrative_area_level_3",
"political"
]
},
{
"long_name": "Greece",
"short_name": "GR",
"types": [
"country",
"political"
]
},
{
"long_name": "546 39",
"short_name": "546 39",
"types": [
"postal_code"
]
}
]
},
"status": "OK"
}
下面是我的Place
模型class
import 'package:json_annotation/json_annotation.dart';
part 'place_model.g.dart';
@JsonSerializable(fieldRename: FieldRename.snake)
class Place {
final String streetName;
final String streetNumber;
final String city;
final String zipCode;
Place({
required this.streetName,
required this.streetNumber,
required this.city,
required this.zipCode,
});
factory Place.fromJson(Map<String, dynamic> json) => _$PlaceFromJson(json);
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'place_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Place _$PlaceFromJson(Map<String, dynamic> json) => Place(
streetName: json['street_name'] as String,
streetNumber: json['street_number'] as String,
city: json['city'] as String,
zipCode: json['zip_code'] as String,
);
Map<String, dynamic> _$PlaceToJson(Place instance) => <String, dynamic>{
'street_name': instance.streetName,
'street_number': instance.streetNumber,
'city': instance.city,
'zip_code': instance.zipCode,
};
我的 Place
模型需要 address_components
列表中的 short_name
值,但是
目前我的模型与 json 架构不匹配。
我是一个没有经验的开发人员,这可能很简单。但是你能建议我一种正确生成 place_model.g.dart
的方法吗?
响应与您的目标不匹配class,因此您必须先转换它。
为响应创建模型:
@JsonSerializable()
class Response {
final Result result;
final String status;
const Response({required this.result, required this.status});
factory Response.fromJson(Map<String, dynamic> json) =>
_$ResponseFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class Result {
final List<AddressComponents> addressComponents;
const Result({required this.addressComponents});
factory Result.fromJson(Map<String, dynamic> json) => _$ResultFromJson(json);
}
@JsonSerializable(fieldRename: FieldRename.snake)
class AddressComponents {
final String longName;
final String shortName;
final List<String> types;
const AddressComponents({
required this.longName,
required this.shortName,
required this.types,
});
factory AddressComponents.fromJson(Map<String, dynamic> json) =>
_$AddressComponentsFromJson(json);
}
现在您可以向 Place
模型添加一个工厂构造函数,它将从 Response
:
Place
模型
class Place {
const Place({
this.streetName,
this.streetNumber,
this.city,
this.zipCode,
});
final String? streetName;
final String? streetNumber;
final String? city;
final String? zipCode;
factory Place.fromResponse(Response response) {
final streetNumberComponent = response.result.addressComponents
.where((c) => c.types.contains('street_number'));
// .. here the rest of Place fields
return Place(
streetNumber: streetNumberComponent.isNotEmpty
? streetNumberComponent.first.shortName
: null,
// .. here the rest of Place fields
);
}
}