嵌套 json 对象的颤振模型

Posted

技术标签:

【中文标题】嵌套 json 对象的颤振模型【英文标题】:Flutter model for nested json object 【发布时间】:2022-01-05 00:02:18 【问题描述】:

我是 Flutter 的新手。我曾尝试在飞镖中开发模型类。但总是显示错误信息

Exception:type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String', tt:#0      new User.fromJson

我不明白,我的代码会在哪里出错。我想要解决方案。

我想在 dart 中转换模型类。

[
    
        "route": 
            "routeID": "aaaaaaaa",
            "routeTitle": "bbbbbbbb"
        ,
        "distributor": 
            "distributorID": "cccccccccccc",
            "distributorName": "ddddddddddd"
        ,
        "visitDate": null
    
]

我已经尝试过我的源代码。如下代码

import 'dart:convert';

List<User> userFromJson(String str) =>
    List<User>.from(json.decode(str).map((x) => User.fromJson(x)));

String userToJson(List<User> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class User 
  User(
    this.visitDate,
    this.route,
    this.distributor,
  );

  String visitDate;
  String route;
  String distributor;

  factory User.fromJson(Map<String, dynamic> json) => User(
    visitDate: json["visitDate"],
    route: json["route"],
    distributor: json["distributor"],
  );

  Map<String, dynamic> toJson() => 
    "visitDate": visitDate,
    "route": route,
    "distributor": distributor,
  ;


Route RouteFromJson(String str) => Route.fromJson(json.decode(str));

String RouteToJson(Route data) => json.encode(data.toJson());

class Route 
  Route(
    this.routeID,
    this.routeTitle,
  );

  String routeID;
  String routeTitle;

  factory Route.fromJson(Map<String, dynamic> json) => Route(
    routeID: json["routeID"],
    routeTitle: json["routeTitle"],
  );

  Map<String, dynamic> toJson() => 
    "routeID": routeID,
    "routeTitle": routeTitle,
  ;

Distributor DistributorFromJson(String str) => Distributor.fromJson(json.decode(str));

String DistributorToJson(Distributor data) => json.encode(data.toJson());
class Distributor 
  Distributor(
    this.distributorID,
    this.distributorName,
  );

  String distributorID;
  String distributorName;

  factory Distributor.fromJson(Map<String, dynamic> json) => Distributor(
    distributorID: json["distributorID"],
    distributorName: json["distributorName"],
  );

  Map<String, dynamic> toJson() => 
    "distributorID": distributorID,
    "distributorName": distributorName,
  ;

如何更正我的模型类。请帮我。谢谢

【问题讨论】:

【参考方案1】:

像这样改变你的用户类:

 class User 
      User(
        this.visitDate,
        this.route,
        this.distributor,
      );
    
      String visitDate;
      Route route;
      Distributor distributor;
    
      factory User.fromJson(Map<String, dynamic> json) => User(
        visitDate: json["visitDate"],
        route = json['route'] != null ? Route.fromJson(json['route']) : null;
        distributor = json['distributor'] != null
            ? Distributor.fromJson(json['distributor'])
            : null;
      );
    
      Map<String, dynamic> toJson() => 
        "visitDate": visitDate,
        if (route != null) 
          data['route'] = this.route.toJson();
        
        if (distributor != null) 
          data['distributor'] = this.distributor.toJson();
        
      ;
    

【讨论】:

【参考方案2】:

您也可以查看json_serializable 包。 这样,您就不必自己编写此代码了。

https://pub.dev/packages/json_serializable

【讨论】:

【参考方案3】:

这是重写模型的方法:

import 'dart:convert';

List<User> usersFromJson(String str) =>
    List<User>.from(json.decode(str).map((x) => User.fromJson(x)));

String usersToJson(List<User> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class User 
  User(
    required this.visitDate,
    required this.route,
    required this.distributor,
  );

  String? visitDate;
  Route route;
  Distributor distributor;

  User.fromJson(Map<String, dynamic> json)
      : visitDate = json["visitDate"],
        route = Route.fromJson(json["route"]),
        distributor = Distributor.fromJson(json["distributor"]);

  Map<String, dynamic> toJson() => 
        "visitDate": visitDate,
        "route": route.toJson(),
        "distributor": distributor.toJson(),
      ;


class Route 
  Route(
    required this.routeID,
    required this.routeTitle,
  );

  String routeID;
  String routeTitle;

  Route.fromJson(Map<String, dynamic> json)
      : routeID = json["routeID"],
        routeTitle = json["routeTitle"];

  Map<String, dynamic> toJson() => 
        "routeID": routeID,
        "routeTitle": routeTitle,
      ;


class Distributor 
  Distributor(
    required this.distributorID,
    required this.distributorName,
  );

  String distributorID;
  String distributorName;

  Distributor.fromJson(Map<String, dynamic> json)
      : distributorID = json["distributorID"],
        distributorName = json["distributorName"];

  Map<String, dynamic> toJson() => 
        "distributorID": distributorID,
        "distributorName": distributorName,
      ;


void main() 
  const data = '''[
    
        "route": 
            "routeID": "aaaaaaaa",
            "routeTitle": "bbbbbbbb"
        ,
        "distributor": 
            "distributorID": "cccccccccccc",
            "distributorName": "ddddddddddd"
        ,
        "visitDate": null
    
  ]''';
  final decoded = usersFromJson(data);
  final encoded = usersToJson(decoded);
  print(decoded);
  print(encoded);

一些注意事项。

您似乎在使用过时的 dart 版本。我建议将项目中的 dart 版本更新为 2.14.0,这是当前最新的主要版本。您可能必须运行 flutter upgrade 才能这样做。您可以在 pubspec.yaml 文件中更改 dart 的版本。 dart 版本的设置如下所示:

environment:
  sdk: ">=2.14.0 <3.0.0"

您在代码中遇到的主要问题是,在您的 User 类中,您已将 routedistributor 定义为 String 类型,而实际上,您希望它们为 Route 类型和Distributor。在 User 类的构造函数中,表达式 json["route"] 将返回类似 "routeID": "aaaaaaaa", "routeTitle": "bbbbbbbb" 的内容,这不是 String 而是 Map&lt;String, dynamic&gt;,这就是您收到上述错误消息的原因。

【讨论】:

【参考方案4】:

颤振盒!

您只需要做简单的工作就是访问以下网站。并且需要将您想要转换的响应或地图/列表放入模型类中,其余将由服务器完成。

顺便说一句, 对于您的 List 数据的模型类是,

// To parse this JSON data, do
//
//     final routeModelClass = routeModelClassFromJson(jsonString);

import 'dart:convert';

List<RouteModelClass> routeModelClassFromJson(String str) => List<RouteModelClass>.from(json.decode(str).map((x) => RouteModelClass.fromJson(x)));

String routeModelClassToJson(List<RouteModelClass> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class RouteModelClass 
    RouteModelClass(
        this.route,
        this.distributor,
        this.visitDate,
    );

    Route route;
    Distributor distributor;
    dynamic visitDate;

    factory RouteModelClass.fromJson(Map<String, dynamic> json) => RouteModelClass(
        route: Route.fromJson(json["route"]),
        distributor: Distributor.fromJson(json["distributor"]),
        visitDate: json["visitDate"],
    );

    Map<String, dynamic> toJson() => 
        "route": route.toJson(),
        "distributor": distributor.toJson(),
        "visitDate": visitDate,
    ;


class Distributor 
    Distributor(
        this.distributorId,
        this.distributorName,
    );

    String distributorId;
    String distributorName;

    factory Distributor.fromJson(Map<String, dynamic> json) => Distributor(
        distributorId: json["distributorID"],
        distributorName: json["distributorName"],
    );

    Map<String, dynamic> toJson() => 
        "distributorID": distributorId,
        "distributorName": distributorName,
    ;


class Route 
    Route(
        this.routeId,
        this.routeTitle,
    );

    String routeId;
    String routeTitle;

    factory Route.fromJson(Map<String, dynamic> json) => Route(
        routeId: json["routeID"],
        routeTitle: json["routeTitle"],
    );

    Map<String, dynamic> toJson() => 
        "routeID": routeId,
        "routeTitle": routeTitle,
    ;

List/Map to Model class

【讨论】:

以上是关于嵌套 json 对象的颤振模型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用颤振访问 JSON 对象?

如何在颤振本地化中读取嵌套的 json?

在颤振中解析json对象

嵌套数组 JSON 的 Mongoose 模型

如何为嵌套 JSON 中存在 JSON 列表的嵌套 JSON 创建模型?

Laravel:一次保存多个模型/ json嵌套输入