Json反序列化cookbook
后,我收到错误消息NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'map' with matching arguments.
捆绑类
class Bundle {
String resourceType;
String id;
String type;
int total;
List<Link> link;
List<Entry> entry;
Bundle(
{this.resourceType,
this.id,
this.type,
this.total,
this.link,
this.entry});
factory Bundle.fromJson(Map<String, dynamic> json) {
return Bundle(
resourceType : json['resourceType'],
id : json['id'],
type : json['type'],
total : json['total'],
);
}
代码:
try {
await parsePerson(resultString);
} catch (e) {
print('Bundlelist Error: $e');
}
Future<List<Bundle>> parsePerson(String body) async {
List<Bundle> bundleList = [];
try {
final parsed = json.decode(body);
bundleList = parsed.map<Bundle>((json) => Bundle.fromJson(json)).toList;
} catch (e) {
print('FutureError: $e');
}
return bundleList;
}
我的结果字符串(部分):完整的json是here。
{"resourceType":"Bundle","id":"f26779b4-5c3c-4c52-83b4-c689516a6a08","type":"searchset","link":[{"relation":"self","url":"https://fhir-open.sandboxcerner.com/dstu2/0b8a0111-e8e6-4c26-a91c-5069cbc6b1ca/Patient?name=b\u0026_count=20"},{"relation":"next","url":"https://fhir-open.sandboxcerner.com/dstu2/0b8a0111-e8e6-4c26-a91c-5069cbc6b1ca/Patient?-pageContext=7018d2bc-6be4-48e1-b8a4-a40f4e98c98c\u0026-pageDirection=NEXT"}],"entry":[{"fullUrl":"https://fhir-open.sandboxcerner.com/dstu2/0b8a0111-e8e6-4c26-a91c-5069cbc6b1ca/Patient/6160015","resource":{"resourceType":"Patient","id":"6160015","meta":{"versionId":"0","lastUpdated":"2019-07-08T20:37:03.000Z"},"text":{"status":"generated","div":"\u003Cdiv\u003E\u003Cp\u003E\u003Cb\u003EPatient\u003C/b\u003E\u003C/p\u003E\u003Cp\u003E\u003Cb\u003EName\u003C/b\u003E: 111d3fcaffb244b2b207c07ffa5a14, bf607a7f1f284e8aa3559d52249bc7\u003C/p\u003E\u003Cp\u003E\u003Cb\u003EDOB\u003C/b\u003E: Mar 15, 1936\u003C/p\u003E\u003Cp\u003E\u003Cb\u003EAdministrative Gend
我从这里尝试过各种建议,包括:
final parsed = jsonDecode(body).cast<Map<String, dynamic>>();
返回
NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments.
我对下一步的尝试感到迷茫。
答案 0 :(得分:2)
您需要一个数组,但您的回答是一张地图
答案 1 :(得分:0)
您的json字符串太长,我无法粘贴包含您的完整json的完整代码
您可以复制粘贴,替换yourjsonstring
并在
下面运行完整代码
您的json字符串包含控制字符\n
,在解析之前需要替换
您可以使用完整代码
代码段
String jsonString = '''yourjsonstring''';
String replaced = jsonString.replaceAll('\n',r'\\n');
final payload = payloadFromJson(replaced);
print(payload.link[0].relation);
print(payload.link[0].url);
print(payload.entry[0].resource.address[0].text);
完整代码
import 'package:flutter/material.dart';
// To parse this JSON data, do
//
// final payload = payloadFromJson(jsonString);
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
String resourceType;
String id;
String type;
List<Link> link;
List<Entry> entry;
Payload({
this.resourceType,
this.id,
this.type,
this.link,
this.entry,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
resourceType: json["resourceType"],
id: json["id"],
type: json["type"],
link: List<Link>.from(json["link"].map((x) => Link.fromJson(x))),
entry: List<Entry>.from(json["entry"].map((x) => Entry.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"resourceType": resourceType,
"id": id,
"type": type,
"link": List<dynamic>.from(link.map((x) => x.toJson())),
"entry": List<dynamic>.from(entry.map((x) => x.toJson())),
};
}
class Entry {
String fullUrl;
Resource resource;
Entry({
this.fullUrl,
this.resource,
});
factory Entry.fromJson(Map<String, dynamic> json) => Entry(
fullUrl: json["fullUrl"],
resource: Resource.fromJson(json["resource"]),
);
Map<String, dynamic> toJson() => {
"fullUrl": fullUrl,
"resource": resource.toJson(),
};
}
class Resource {
ResourceType resourceType;
String id;
Meta meta;
TextClass text;
List<Identifier> identifier;
bool active;
List<Name> name;
List<Telecom> telecom;
Gender gender;
DateTime birthDate;
List<Address> address;
Resource({
this.resourceType,
this.id,
this.meta,
this.text,
this.identifier,
this.active,
this.name,
this.telecom,
this.gender,
this.birthDate,
this.address,
});
factory Resource.fromJson(Map<String, dynamic> json) => Resource(
resourceType: resourceTypeValues.map[json["resourceType"]],
id: json["id"],
meta: Meta.fromJson(json["meta"]),
text: TextClass.fromJson(json["text"]),
identifier: List<Identifier>.from(json["identifier"].map((x) => Identifier.fromJson(x))),
active: json["active"],
name: List<Name>.from(json["name"].map((x) => Name.fromJson(x))),
telecom: List<Telecom>.from(json["telecom"].map((x) => Telecom.fromJson(x))),
gender: genderValues.map[json["gender"]],
birthDate: DateTime.parse(json["birthDate"]),
address: List<Address>.from(json["address"].map((x) => Address.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"resourceType": resourceTypeValues.reverse[resourceType],
"id": id,
"meta": meta.toJson(),
"text": text.toJson(),
"identifier": List<dynamic>.from(identifier.map((x) => x.toJson())),
"active": active,
"name": List<dynamic>.from(name.map((x) => x.toJson())),
"telecom": List<dynamic>.from(telecom.map((x) => x.toJson())),
"gender": genderValues.reverse[gender],
"birthDate": "${birthDate.year.toString().padLeft(4, '0')}-${birthDate.month.toString().padLeft(2, '0')}-${birthDate.day.toString().padLeft(2, '0')}",
"address": List<dynamic>.from(address.map((x) => x.toJson())),
};
}
class Address {
AddressUse use;
String text;
List<String> line;
String city;
String state;
String postalCode;
String country;
AddressPeriod period;
Address({
this.use,
this.text,
this.line,
this.city,
this.state,
this.postalCode,
this.country,
this.period,
});
factory Address.fromJson(Map<String, dynamic> json) => Address(
use: addressUseValues.map[json["use"]],
text: json["text"],
line: List<String>.from(json["line"].map((x) => x)),
city: json["city"],
state: json["state"],
postalCode: json["postalCode"],
country: json["country"],
period: json["period"] == null ? null : AddressPeriod.fromJson(json["period"]),
);
Map<String, dynamic> toJson() => {
"use": addressUseValues.reverse[use],
"text": text,
"line": List<dynamic>.from(line.map((x) => x)),
"city": city,
"state": state,
"postalCode": postalCode,
"country": country,
"period": period == null ? null : period.toJson(),
};
}
class AddressPeriod {
DateTime start;
AddressPeriod({
this.start,
});
factory AddressPeriod.fromJson(Map<String, dynamic> json) => AddressPeriod(
start: DateTime.parse(json["start"]),
);
Map<String, dynamic> toJson() => {
"start": start.toIso8601String(),
};
}
enum AddressUse { HOME, WORK, MOBILE }
final addressUseValues = EnumValues({
"home": AddressUse.HOME,
"mobile": AddressUse.MOBILE,
"work": AddressUse.WORK
});
enum Gender { UNKNOWN, OTHER }
final genderValues = EnumValues({
"other": Gender.OTHER,
"unknown": Gender.UNKNOWN
});
class Identifier {
IdentifierUse use;
Type type;
IdentifierSystem system;
String identifierValue;
Value value;
AddressPeriod period;
Identifier({
this.use,
this.type,
this.system,
this.identifierValue,
this.value,
this.period,
});
factory Identifier.fromJson(Map<String, dynamic> json) => Identifier(
use: identifierUseValues.map[json["use"]],
type: Type.fromJson(json["type"]),
system: identifierSystemValues.map[json["system"]],
identifierValue: json["value"],
value: Value.fromJson(json["_value"]),
period: AddressPeriod.fromJson(json["period"]),
);
Map<String, dynamic> toJson() => {
"use": identifierUseValues.reverse[use],
"type": type.toJson(),
"system": identifierSystemValues.reverse[system],
"value": identifierValue,
"_value": value.toJson(),
"period": period.toJson(),
};
}
enum IdentifierSystem { URN_OID_2168401113883378700, URN_OID_111111, URN_OID_21684011138833421000110000112 }
final identifierSystemValues = EnumValues({
"urn:oid:1.1.1.1.1.1": IdentifierSystem.URN_OID_111111,
"urn:oid:2.16.840.1.113883.3.42.10001.100001.12": IdentifierSystem.URN_OID_21684011138833421000110000112,
"urn:oid:2.16.840.1.113883.3.787.0.0": IdentifierSystem.URN_OID_2168401113883378700
});
class Type {
List<Coding> coding;
TextEnum text;
Type({
this.coding,
this.text,
});
factory Type.fromJson(Map<String, dynamic> json) => Type(
coding: json["coding"] == null ? null : List<Coding>.from(json["coding"].map((x) => Coding.fromJson(x))),
text: textEnumValues.map[json["text"]],
);
Map<String, dynamic> toJson() => {
"coding": coding == null ? null : List<dynamic>.from(coding.map((x) => x.toJson())),
"text": textEnumValues.reverse[text],
};
}
class Coding {
String system;
Code code;
Display display;
bool userSelected;
Coding({
this.system,
this.code,
this.display,
this.userSelected,
});
factory Coding.fromJson(Map<String, dynamic> json) => Coding(
system: json["system"],
code: codeValues.map[json["code"]],
display: displayValues.map[json["display"]],
userSelected: json["userSelected"],
);
Map<String, dynamic> toJson() => {
"system": system,
"code": codeValues.reverse[code],
"display": displayValues.reverse[display],
"userSelected": userSelected,
};
}
enum Code { MR }
final codeValues = EnumValues({
"MR": Code.MR
});
enum Display { MEDICAL_RECORD_NUMBER }
final displayValues = EnumValues({
"Medical record number": Display.MEDICAL_RECORD_NUMBER
});
enum TextEnum { COMMUNITY_MEDICAL_RECORD_NUMBER, MRN, MILITARY_ID }
final textEnumValues = EnumValues({
"Community Medical Record Number": TextEnum.COMMUNITY_MEDICAL_RECORD_NUMBER,
"Military Id": TextEnum.MILITARY_ID,
"MRN": TextEnum.MRN
});
enum IdentifierUse { USUAL }
final identifierUseValues = EnumValues({
"usual": IdentifierUse.USUAL
});
class Value {
List<Extension> extension;
Value({
this.extension,
});
factory Value.fromJson(Map<String, dynamic> json) => Value(
extension: List<Extension>.from(json["extension"].map((x) => Extension.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"extension": List<dynamic>.from(extension.map((x) => x.toJson())),
};
}
class Extension {
String url;
String valueString;
Extension({
this.url,
this.valueString,
});
factory Extension.fromJson(Map<String, dynamic> json) => Extension(
url: json["url"],
valueString: json["valueString"],
);
Map<String, dynamic> toJson() => {
"url": url,
"valueString": valueString,
};
}
class Meta {
String versionId;
DateTime lastUpdated;
Meta({
this.versionId,
this.lastUpdated,
});
factory Meta.fromJson(Map<String, dynamic> json) => Meta(
versionId: json["versionId"],
lastUpdated: DateTime.parse(json["lastUpdated"]),
);
Map<String, dynamic> toJson() => {
"versionId": versionId,
"lastUpdated": lastUpdated.toIso8601String(),
};
}
class Name {
NameUse use;
String text;
List<String> family;
List<String> given;
List<String> prefix;
NamePeriod period;
List<String> suffix;
Name({
this.use,
this.text,
this.family,
this.given,
this.prefix,
this.period,
this.suffix,
});
factory Name.fromJson(Map<String, dynamic> json) => Name(
use: nameUseValues.map[json["use"]],
text: json["text"],
family: List<String>.from(json["family"].map((x) => x)),
given: List<String>.from(json["given"].map((x) => x)),
prefix: json["prefix"] == null ? null : List<String>.from(json["prefix"].map((x) => x)),
period: json["period"] == null ? null : NamePeriod.fromJson(json["period"]),
suffix: json["suffix"] == null ? null : List<String>.from(json["suffix"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"use": nameUseValues.reverse[use],
"text": text,
"family": List<dynamic>.from(family.map((x) => x)),
"given": List<dynamic>.from(given.map((x) => x)),
"prefix": prefix == null ? null : List<dynamic>.from(prefix.map((x) => x)),
"period": period == null ? null : period.toJson(),
"suffix": suffix == null ? null : List<dynamic>.from(suffix.map((x) => x)),
};
}
class NamePeriod {
DateTime start;
DateTime end;
NamePeriod({
this.start,
this.end,
});
factory NamePeriod.fromJson(Map<String, dynamic> json) => NamePeriod(
start: json["start"] == null ? null : DateTime.parse(json["start"]),
end: json["end"] == null ? null : DateTime.parse(json["end"]),
);
Map<String, dynamic> toJson() => {
"start": start == null ? null : start.toIso8601String(),
"end": end == null ? null : end.toIso8601String(),
};
}
enum NameUse { OFFICIAL, OLD }
final nameUseValues = EnumValues({
"official": NameUse.OFFICIAL,
"old": NameUse.OLD
});
enum ResourceType { PATIENT }
final resourceTypeValues = EnumValues({
"Patient": ResourceType.PATIENT
});
class Telecom {
TelecomSystem system;
ValueEnum value;
AddressUse use;
AddressPeriod period;
Telecom({
this.system,
this.value,
this.use,
this.period,
});
factory Telecom.fromJson(Map<String, dynamic> json) => Telecom(
system: telecomSystemValues.map[json["system"]],
value: valueEnumValues.map[json["value"]],
use: addressUseValues.map[json["use"]],
period: json["period"] == null ? null : AddressPeriod.fromJson(json["period"]),
);
Map<String, dynamic> toJson() => {
"system": telecomSystemValues.reverse[system],
"value": valueEnumValues.reverse[value],
"use": addressUseValues.reverse[use],
"period": period == null ? null : period.toJson(),
};
}
enum TelecomSystem { PHONE, EMAIL }
final telecomSystemValues = EnumValues({
"email": TelecomSystem.EMAIL,
"phone": TelecomSystem.PHONE
});
enum ValueEnum { THE_3213213213, NAME_FAKEMAIL_COM, THE_8888888888 }
final valueEnumValues = EnumValues({
"name@fakemail.com": ValueEnum.NAME_FAKEMAIL_COM,
"321-321-3213": ValueEnum.THE_3213213213,
"888-888-8888": ValueEnum.THE_8888888888
});
class TextClass {
Status status;
String div;
TextClass({
this.status,
this.div,
});
factory TextClass.fromJson(Map<String, dynamic> json) => TextClass(
status: statusValues.map[json["status"]],
div: json["div"],
);
Map<String, dynamic> toJson() => {
"status": statusValues.reverse[status],
"div": div,
};
}
enum Status { GENERATED }
final statusValues = EnumValues({
"generated": Status.GENERATED
});
class Link {
String relation;
String url;
Link({
this.relation,
this.url,
});
factory Link.fromJson(Map<String, dynamic> json) => Link(
relation: json["relation"],
url: json["url"],
);
Map<String, dynamic> toJson() => {
"relation": relation,
"url": url,
};
}
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String jsonString = '''yourjsonstring''';
//String jsonString = '''{"newLine": "here is a \n newline \u003E \u0026 \u003C aaa"}''';
void _incrementCounter() {
String replaced = jsonString.replaceAll('\n',r'\\n');
final payload = payloadFromJson(replaced);
print(payload.link[0].relation);
print(payload.link[0].url);
print(payload.entry[0].resource.address[0].text);
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}