json - 由于子类型错误,无法从 Internet 加载 json 数据:列表不是类型 Map
问题描述
我是 Flutter 的新手,我想从 API 获取 json 数据。我正在使用可序列化的 json。
这是我从互联网上获取数据的代码:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_json_widget/flutter_json_widget.dart';
import './JsonDataMeter.dart';
Future<Meter> fetchMeter() async {
final response = await http.get(
'the url');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Meter.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load meter');
}
}
class MeterList extends StatefulWidget {
MeterList({Key key, }) : super(key: key);
@override
_MeterList createState() => _MeterList();
}
class _MeterList extends State<MeterList> {
Future<Meter> futureMeter;
@override
void initState(){
super.initState();
futureMeter = fetchMeter();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Meter>(
future: futureMeter,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.address.city);
} else if (snapshot.hasError) {
//return Text("${snapshot.error}");
print(snapshot.error);
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
);
}
这是我创建类的地方,其中包含 json 数据:
import 'package:json_annotation/json_annotation.dart';
part 'JsonDataMeter.g.dart';
@JsonSerializable(explicitToJson: true)
class Meter{
Address address;
List<Apartments> apartments;
Meter({this.address, this.apartments});
factory Meter.fromJson(Map<String,dynamic> json) => _$MeterFromJson(json);
Map<String,dynamic> toJson() => _$MeterToJson(this);
}
@JsonSerializable()
class Address {
String streetAndNumber;
int PLZ;
String city;
Address({this.streetAndNumber, this.PLZ, this.city});
factory Address.fromJson(Map<String, dynamic> json) =>
_$AddressFromJson(json);
Map<String,dynamic> toJson() => _$AddressToJson(this);
}
@JsonSerializable(explicitToJson: true)
class Apartments{
Tenants tenants;
List<AssignedMeter> assignedMeter;
String id;
Meters meters;
String location;
int area;
String belongingProperty;
int v;
Apartments({this.tenants,this.assignedMeter, this.id, this.meters, this.location, this.area, this.belongingProperty, this.v});
factory Apartments.fromJson(Map<String,dynamic> json) => _$ApartmentsFromJson(json);
Map<String,dynamic> toJson() => _$ApartmentsToJson(this);
}
@JsonSerializable()
class Tenants{
String id;
String name;
String belongingApartment;
String timeInApartment;
int prepayment;
int v;
UsageTimes usageTimes;
AssociatedApartments associatedApartments;
Tenants({this.id,this.name, this.belongingApartment, this.timeInApartment, this.prepayment, this.v, this.usageTimes, this.associatedApartments});
factory Tenants.fromJson(Map<String,dynamic> json) => _$TenantsFromJson(json);
Map<String,dynamic> toJson() => _$TenantsToJson(this);
}
@JsonSerializable()
class UsageTimes{
String id;
String usageTime;
int usedArea;
UsageTimes({this.id, this.usageTime, this.usedArea});
factory UsageTimes.fromJson(Map<String,dynamic> json) => _$UsageTimesFromJson(json);
Map<String,dynamic> toJson() => _$UsageTimesToJson(this);
}
@JsonSerializable()
class AssociatedApartments{
UsageTimes usageTimes;
String id;
String apartmentID;
String timeInApartment;
AssociatedApartments({this.usageTimes, this.id, this.apartmentID, this.timeInApartment});
factory AssociatedApartments.fromJson(Map<String,dynamic> json) => _$AssociatedApartmentsFromJson(json);
Map<String,dynamic> toJson() => _$AssociatedApartmentsToJson(this);
}
@JsonSerializable()
class AssignedMeter{
String id;
MeterReadings meterReadings;
String belongingApartment;
String meterNumber;
String meterType;
int v;
AssignedMeter({this.id, this.meterReadings, this.belongingApartment, this.meterNumber, this.meterType, this.v});
factory AssignedMeter.fromJson(Map<String,dynamic> json) => _$AssignedMeterFromJson(json);
Map<String,dynamic> toJson() => _$AssignedMeterToJson(this);
}
@JsonSerializable()
class MeterReadings {
String id;
String date;
String value;
MeterReadings({this.id, this.date, this.value});
factory MeterReadings.fromJson(Map<String,dynamic> json) => _$MeterReadingsFromJson(json);
Map<String,dynamic> toJson() => _$MeterReadingsToJson(this);
}
@JsonSerializable()
class Meters{
String id;
String dateStart;
String dateEnd;
int waterStart;
int waterEnd;
int powerStart;
int powerEnd;
Meters({this.id, this.dateStart, this.dateEnd, this.waterStart, this.waterEnd, this.powerStart, this.powerEnd});
factory Meters.fromJson(Map<String,dynamic> json) => _$MetersFromJson(json);
Map<String,dynamic> toJson() => _$MetersToJson(this);
}
这是 JsonSerializable 自动生成的代码:
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'JsonDataMeter.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Meter _$MeterFromJson(Map<String, dynamic> json) {
return Meter(
address: json['address'] == null
? null
: Address.fromJson(json['address'] as Map<String, dynamic>),
apartments: (json['apartments'] as List)
?.map((e) =>
e == null ? null : Apartments.fromJson(e as Map<String, dynamic>))
?.toList(),
);
}
Map<String, dynamic> _$MeterToJson(Meter instance) => <String, dynamic>{
'address': instance.address,
'apartments': instance.apartments,
};
Address _$AddressFromJson(Map<String, dynamic> json) {
return Address(
streetAndNumber: json['streetAndNumber'] as String,
PLZ: json['PLZ'] as int,
city: json['city'] as String,
);
}
Map<String, dynamic> _$AddressToJson(Address instance) => <String, dynamic>{
'streetAndNumber': instance.streetAndNumber,
'PLZ': instance.PLZ,
'city': instance.city,
};
Apartments _$ApartmentsFromJson(Map<String, dynamic> json) {
return Apartments(
tenants: json['tenants'] == null
? null
: Tenants.fromJson(json['tenants'] as Map<String, dynamic>),
assignedMeter: (json['assignedMeter'] as List)
?.map((e) => e == null
? null
: AssignedMeter.fromJson(e as Map<String, dynamic>))
?.toList(),
id: json['id'] as String,
meters: json['meters'] == null
? null
: Meters.fromJson(json['meters'] as Map<String, dynamic>),
location: json['location'] as String,
area: json['area'] as int,
belongingProperty: json['belongingProperty'] as String,
v: json['v'] as int,
);
}
Map<String, dynamic> _$ApartmentsToJson(Apartments instance) =>
<String, dynamic>{
'tenants': instance.tenants,
'assignedMeter': instance.assignedMeter,
'id': instance.id,
'meters': instance.meters,
'location': instance.location,
'area': instance.area,
'belongingProperty': instance.belongingProperty,
'v': instance.v,
};
Tenants _$TenantsFromJson(Map<String, dynamic> json) {
return Tenants(
id: json['id'] as String,
name: json['name'] as String,
belongingApartment: json['belongingApartment'] as String,
timeInApartment: json['timeInApartment'] as String,
prepayment: json['prepayment'] as int,
v: json['v'] as int,
usageTimes: json['usageTimes'] == null
? null
: UsageTimes.fromJson(json['usageTimes'] as Map<String, dynamic>),
associatedApartments: json['associatedApartments'] == null
? null
: AssociatedApartments.fromJson(
json['associatedApartments'] as Map<String, dynamic>),
);
}
Map<String, dynamic> _$TenantsToJson(Tenants instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'belongingApartment': instance.belongingApartment,
'timeInApartment': instance.timeInApartment,
'prepayment': instance.prepayment,
'v': instance.v,
'usageTimes': instance.usageTimes,
'associatedApartments': instance.associatedApartments,
};
UsageTimes _$UsageTimesFromJson(Map<String, dynamic> json) {
return UsageTimes(
id: json['id'] as String,
usageTime: json['usageTime'] as String,
usedArea: json['usedArea'] as int,
);
}
Map<String, dynamic> _$UsageTimesToJson(UsageTimes instance) =>
<String, dynamic>{
'id': instance.id,
'usageTime': instance.usageTime,
'usedArea': instance.usedArea,
};
AssociatedApartments _$AssociatedApartmentsFromJson(Map<String, dynamic> json) {
return AssociatedApartments(
usageTimes: json['usageTimes'] == null
? null
: UsageTimes.fromJson(json['usageTimes'] as Map<String, dynamic>),
id: json['id'] as String,
apartmentID: json['apartmentID'] as String,
timeInApartment: json['timeInApartment'] as String,
);
}
Map<String, dynamic> _$AssociatedApartmentsToJson(
AssociatedApartments instance) =>
<String, dynamic>{
'usageTimes': instance.usageTimes,
'id': instance.id,
'apartmentID': instance.apartmentID,
'timeInApartment': instance.timeInApartment,
};
AssignedMeter _$AssignedMeterFromJson(Map<String, dynamic> json) {
return AssignedMeter(
id: json['id'] as String,
meterReadings: json['meterReadings'] == null
? null
: MeterReadings.fromJson(json['meterReadings'] as Map<String, dynamic>),
belongingApartment: json['belongingApartment'] as String,
meterNumber: json['meterNumber'] as String,
meterType: json['meterType'] as String,
v: json['v'] as int,
);
}
Map<String, dynamic> _$AssignedMeterToJson(AssignedMeter instance) =>
<String, dynamic>{
'id': instance.id,
'meterReadings': instance.meterReadings,
'belongingApartment': instance.belongingApartment,
'meterNumber': instance.meterNumber,
'meterType': instance.meterType,
'v': instance.v,
};
MeterReadings _$MeterReadingsFromJson(Map<String, dynamic> json) {
return MeterReadings(
id: json['id'] as String,
date: json['date'] as String,
value: json['value'] as String,
);
}
Map<String, dynamic> _$MeterReadingsToJson(MeterReadings instance) =>
<String, dynamic>{
'id': instance.id,
'date': instance.date,
'value': instance.value,
};
Meters _$MetersFromJson(Map<String, dynamic> json) {
return Meters(
id: json['id'] as String,
dateStart: json['dateStart'] as String,
dateEnd: json['dateEnd'] as String,
waterStart: json['waterStart'] as int,
waterEnd: json['waterEnd'] as int,
powerStart: json['powerStart'] as int,
powerEnd: json['powerEnd'] as int,
);
}
Map<String, dynamic> _$MetersToJson(Meters instance) => <String, dynamic>{
'id': instance.id,
'dateStart': instance.dateStart,
'dateEnd': instance.dateEnd,
'waterStart': instance.waterStart,
'waterEnd': instance.waterEnd,
'powerStart': instance.powerStart,
'powerEnd': instance.powerEnd,
};
最后这是我要获取的 json(不是原始值):
{
"address": {
"streetAndNumber": "SomeData",
"PLZ": 1,
"city": "SomeData"
},
"apartments": [
{
"tenants": [
{
"_id": "SomeData",
"name": "SomeData",
"belongingApartment": "SomeData",
"timeInApartment": "SomeData",
"prepayment": 1,
"__v": 1,
"usageTimes": [
{
"_id": "SomeData",
"usageTime": "SomeData",
"usedArea": 1
}
],
"associatedApartments": [
{
"usageTimes": [
{
"_id": "SomeData",
"usageTime": "SomeData",
"usedArea": 1
}
],
"_id": "SomeData",
"apartmentID": "SomeData",
"timeInApartment": "SomeData"
}
]
}
],
"assignedMeters": [
{
"_id": "SomeData",
"meterReadings": [
{
"_id": "SomeData",
"date": "SomeData",
"value": 1
}
],
"belongingApartment": "SomeData",
"meterNumber": "SomeData",
"meterType": "SomeData",
"__v": 1
},
{
"_id": "SomeData",
"meterReadings": [
{
"_id": "SomeData",
"date": "SomeData",
"value": 1
}
],
"belongingApartment": "SomeData",
"meterNumber": "SomeData",
"meterType": "SomeData",
"__v": 1
},
{
"_id": "SomeData",
"meterReadings": [
{
"_id": "SomeData",
"date": "SomeData",
"value": 1
},
{
"_id": "SomeData",
"date": "SomeData",
"value": 1
}
],
"belongingApartment": "SomeData",
"meterNumber": "SomeData",
"meterType": "SomeData",
"__v": 1
}
],
"_id": "SomeData",
"meters": [
{
"_id": "SomeData",
"dateStart": "SomeData",
"dateEnd": "SomeData",
"waterStart": 1,
"waterEnd": 1,
"powerStart": 1,
"powerEnd": 1
}
],
"location": "SomeData",
"area": 1,
"belongingProperty": "SomeData",
"__v": 1
},
我总是得到错误:
I/flutter ( 4626): type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast
正如我所说,我是 Flutter 的新手,这可能只是一个非常愚蠢的错误,但请帮助我,我觉得我尝试了一切,但我不知道该怎么做。非常感谢。
解决方案
问题在于您的模型。例如:在公寓模型租户中,仪表应为 List<...> 类型。
在租户模型 usageTimes 中, associatedApartments 应该是 List<..> 类型。在 associatedApartments 模型中,usageTimes 应该是 List<...> 类型。
我使用此链接https://javiercbk.github.io/json_to_dart/从您的 json 生成了一个新的响应模型。
试试看。
class MeterListResponse {
Address address;
List<Apartments> apartments;
MeterListResponse({this.address, this.apartments});
MeterListResponse.fromJson(Map<String, dynamic> json) {
address =
json['address'] != null ? new Address.fromJson(json['address']) : null;
if (json['apartments'] != null) {
apartments = new List<Apartments>();
json['apartments'].forEach((v) {
apartments.add(new Apartments.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.address != null) {
data['address'] = this.address.toJson();
}
if (this.apartments != null) {
data['apartments'] = this.apartments.map((v) => v.toJson()).toList();
}
return data;
}
}
class Address {
String streetAndNumber;
int pLZ;
String city;
Address({this.streetAndNumber, this.pLZ, this.city});
Address.fromJson(Map<String, dynamic> json) {
streetAndNumber = json['streetAndNumber'];
pLZ = json['PLZ'];
city = json['city'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['streetAndNumber'] = this.streetAndNumber;
data['PLZ'] = this.pLZ;
data['city'] = this.city;
return data;
}
}
class Apartments {
List<Tenants> tenants;
List<AssignedMeters> assignedMeters;
String sId;
List<Meters> meters;
String location;
int area;
String belongingProperty;
int iV;
Apartments(
{this.tenants,
this.assignedMeters,
this.sId,
this.meters,
this.location,
this.area,
this.belongingProperty,
this.iV});
Apartments.fromJson(Map<String, dynamic> json) {
if (json['tenants'] != null) {
tenants = new List<Tenants>();
json['tenants'].forEach((v) {
tenants.add(new Tenants.fromJson(v));
});
}
if (json['assignedMeters'] != null) {
assignedMeters = new List<AssignedMeters>();
json['assignedMeters'].forEach((v) {
assignedMeters.add(new AssignedMeters.fromJson(v));
});
}
sId = json['_id'];
if (json['meters'] != null) {
meters = new List<Meters>();
json['meters'].forEach((v) {
meters.add(new Meters.fromJson(v));
});
}
location = json['location'];
area = json['area'];
belongingProperty = json['belongingProperty'];
iV = json['__v'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.tenants != null) {
data['tenants'] = this.tenants.map((v) => v.toJson()).toList();
}
if (this.assignedMeters != null) {
data['assignedMeters'] =
this.assignedMeters.map((v) => v.toJson()).toList();
}
data['_id'] = this.sId;
if (this.meters != null) {
data['meters'] = this.meters.map((v) => v.toJson()).toList();
}
data['location'] = this.location;
data['area'] = this.area;
data['belongingProperty'] = this.belongingProperty;
data['__v'] = this.iV;
return data;
}
}
class Tenants {
String sId;
String name;
String belongingApartment;
String timeInApartment;
int prepayment;
int iV;
List<UsageTimes> usageTimes;
List<AssociatedApartments> associatedApartments;
Tenants(
{this.sId,
this.name,
this.belongingApartment,
this.timeInApartment,
this.prepayment,
this.iV,
this.usageTimes,
this.associatedApartments});
Tenants.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
name = json['name'];
belongingApartment = json['belongingApartment'];
timeInApartment = json['timeInApartment'];
prepayment = json['prepayment'];
iV = json['__v'];
if (json['usageTimes'] != null) {
usageTimes = new List<UsageTimes>();
json['usageTimes'].forEach((v) {
usageTimes.add(new UsageTimes.fromJson(v));
});
}
if (json['associatedApartments'] != null) {
associatedApartments = new List<AssociatedApartments>();
json['associatedApartments'].forEach((v) {
associatedApartments.add(new AssociatedApartments.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['_id'] = this.sId;
data['name'] = this.name;
data['belongingApartment'] = this.belongingApartment;
data['timeInApartment'] = this.timeInApartment;
data['prepayment'] = this.prepayment;
data['__v'] = this.iV;
if (this.usageTimes != null) {
data['usageTimes'] = this.usageTimes.map((v) => v.toJson()).toList();
}
if (this.associatedApartments != null) {
data['associatedApartments'] =
this.associatedApartments.map((v) => v.toJson()).toList();
}
return data;
}
}
class UsageTimes {
String sId;
String usageTime;
int usedArea;
UsageTimes({this.sId, this.usageTime, this.usedArea});
UsageTimes.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
usageTime = json['usageTime'];
usedArea = json['usedArea'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['_id'] = this.sId;
data['usageTime'] = this.usageTime;
data['usedArea'] = this.usedArea;
return data;
}
}
class AssociatedApartments {
List<UsageTimes> usageTimes;
String sId;
String apartmentID;
String timeInApartment;
AssociatedApartments(
{this.usageTimes, this.sId, this.apartmentID, this.timeInApartment});
AssociatedApartments.fromJson(Map<String, dynamic> json) {
if (json['usageTimes'] != null) {
usageTimes = new List<UsageTimes>();
json['usageTimes'].forEach((v) {
usageTimes.add(new UsageTimes.fromJson(v));
});
}
sId = json['_id'];
apartmentID = json['apartmentID'];
timeInApartment = json['timeInApartment'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.usageTimes != null) {
data['usageTimes'] = this.usageTimes.map((v) => v.toJson()).toList();
}
data['_id'] = this.sId;
data['apartmentID'] = this.apartmentID;
data['timeInApartment'] = this.timeInApartment;
return data;
}
}
class AssignedMeters {
String sId;
List<MeterReadings> meterReadings;
String belongingApartment;
String meterNumber;
String meterType;
int iV;
AssignedMeters(
{this.sId,
this.meterReadings,
this.belongingApartment,
this.meterNumber,
this.meterType,
this.iV});
AssignedMeters.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
if (json['meterReadings'] != null) {
meterReadings = new List<MeterReadings>();
json['meterReadings'].forEach((v) {
meterReadings.add(new MeterReadings.fromJson(v));
});
}
belongingApartment = json['belongingApartment'];
meterNumber = json['meterNumber'];
meterType = json['meterType'];
iV = json['__v'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['_id'] = this.sId;
if (this.meterReadings != null) {
data['meterReadings'] =
this.meterReadings.map((v) => v.toJson()).toList();
}
data['belongingApartment'] = this.belongingApartment;
data['meterNumber'] = this.meterNumber;
data['meterType'] = this.meterType;
data['__v'] = this.iV;
return data;
}
}
class MeterReadings {
String sId;
String date;
int value;
MeterReadings({this.sId, this.date, this.value});
MeterReadings.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
date = json['date'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['_id'] = this.sId;
data['date'] = this.date;
data['value'] = this.value;
return data;
}
}
class Meters {
String sId;
String dateStart;
String dateEnd;
int waterStart;
int waterEnd;
int powerStart;
int powerEnd;
Meters(
{this.sId,
this.dateStart,
this.dateEnd,
this.waterStart,
this.waterEnd,
this.powerStart,
this.powerEnd});
Meters.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
dateStart = json['dateStart'];
dateEnd = json['dateEnd'];
waterStart = json['waterStart'];
waterEnd = json['waterEnd'];
powerStart = json['powerStart'];
powerEnd = json['powerEnd'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['_id'] = this.sId;
data['dateStart'] = this.dateStart;
data['dateEnd'] = this.dateEnd;
data['waterStart'] = this.waterStart;
data['waterEnd'] = this.waterEnd;
data['powerStart'] = this.powerStart;
data['powerEnd'] = this.powerEnd;
return data;
}
}
推荐阅读
- pine-script - 如何将 Pivot Points H/L 与 TradingView Pine 中的一条线连接起来?
- sql - 如何否定无效的订单数据?
- php - 替换文件中的单词,使用 PHP 中的另一个文件
- c++ - 运算符 [] 重载更新 2 个值 c++
- vba - Excel VBA 工作表更改事件导致消息框出现多次
- java - 为什么我们需要双重定义从 main 传递到方法的变量?
- javascript - Ajax 在新的 HTML 内容代码之后总是返回“1”
- angularjs - 如何增加帖子参数列表的大小
- javascript - 使用箭头键选择列表的子 li 元素
- xcode - Swift 4 - 表达式类型'@lvalue String?' 没有更多上下文是模棱两可的