Flutter / Dart错误-NoSuchMethodError:类'_InternalLinkedHashMap <String,dynamic>'没有实例方法'map'具有匹配的参数

时间:2020-01-10 01:42:44

标签: json flutter dart deserialization

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.

我对下一步的尝试感到迷茫。

2 个答案:

答案 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),
      ), 
    );
  }
}