繁体   English   中英

如何解析 dart 中的嵌套 Json

[英]How to parse Nested Json in dart

我对解析 Dart / flutter 中的嵌套 JSON 有点困惑。 到目前为止,我有下面的代码,但我不断收到以下错误消息:“必须初始化不可为空的实例字段 'latepointBookings' 和 'usermetas'”。 我目前在传递latepoint_bookings 和usermetas 的嵌套值时遇到问题。 请有人可以帮助解释我做错了什么并指出我正确的方向。 谢谢你。

这是我的 JSON 文件:

{
   "user":{
      "id":25,
      "username":"johndoe",
      "nicename":"johndoe",
      "email":"johndoe@gmail.com",
      "url":"",
      "registered":"2022-01-18 18:00:51",
      "displayname":"David Tunde",
      "firstname":"John",
      "lastname":"Doe",
      "nickname":"johndoe",
      "description":"Sample description",
      "capabilities":{
         "subscriber":true
      },
      "role":[
         "subscriber"
      ],
      "shipping":null,
      "billing":null,
      "avatar":"https://secure.gravatar.com/avatar/976c30dff95752dd1a273b750500154a?s=96&d=mm&r=g",
      "is_driver_available":null,
      "dokan_enable_selling":"",
      "gamipress_point_points":"100",
      "latepoint_bookings":[
         {
            "id":"28",
            "start_date":"2020-10-01",
            "start_time":"870",
            "status":"approved"
         },
         {
            "id":"29",
            "start_date":"2020-09-28",
            "start_time":"870",
            "status":"approved"
         }
      ],
      "usermetas":{
         "rich_editing":[
            "true"
         ],
         "syntax_highlighting":[
            "true"
         ],
         "comment_shortcuts":[
            "false"
         ],
         "admin_color":[
            "fresh"
         ],
         "use_ssl":[
            "0"
         ]
      }
   }
}

下面是我的 dart 代码。

class User {

  String? id;
  bool? loggedIn;
  String? name;
  String? firstName;
  String? lastName;
  String? username;
  String? email;
  String? nicename;
  String? userUrl;
  String? picture;
  String? cookie;
  String? jwtToken;
  bool isVender = false;
  bool isDeliveryBoy = false;
  bool? isSocial = false;
  bool? isDriverAvailable;
  String? gamipressPointPoints;
  List<LatepointBooking> latepointBookings;
  Map<String, List<String>> usermetas;

  User(
        this.latepointBookings,
        this.usermetas,
    );

  String get fullName =>
      name ?? [firstName ?? '', lastName ?? ''].join(' ').trim();

  String? role;


  User.fromJson(Map<String, dynamic> json) {
    try {
      isSocial = json['isSocial'] ?? false;
      loggedIn = json['loggedIn'];
      id = json['id'].toString();
      cookie = json['cookie'];
      username = json['username'];
      nicename = json['nicename'];
      firstName = json['firstName'];
      lastName = json['lastName'];
      name = json['displayname'] ??
          json['displayName'] ??
          '${firstName ?? ''}${(lastName?.isEmpty ?? true) ? '' : ' $lastName'}';

      email = json['email'] ?? id;
      userUrl = json['avatar'];
    } catch (e) {
      printLog(e.toString());
    }
  }



  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'loggedIn': loggedIn,
      'name': name,
      'firstName': firstName,
      'lastName': lastName,
      'username': username,
      'email': email,
      'picture': picture,
      'cookie': cookie,
      'nicename': nicename,
      'url': userUrl,
      'isSocial': isSocial,
      'isVender': isVender,
      'jwtToken': jwtToken,
      'role': role,
      'gamipress_point_points': gamipressPointPoints,
      'latepoint_bookings': List<dynamic>.from(latepointBookings.map((x) => x.toJson())),
      'usermetas': Map.from(usermetas).map((k, v) => MapEntry<String, dynamic>(k, List<dynamic>.from(v.map((x) => x)))),
    };
  }
}

class LatepointBooking {
  LatepointBooking({
    required this.id,
    required this.startDate,
    required this.startTime,
    required this.status,
  });

  String id;
  DateTime startDate;
  String startTime;
  String status;

  factory LatepointBooking.fromJson(Map<String, dynamic> json) => LatepointBooking(
    id: json['id'],
    startDate: DateTime.parse(json['start_date']),
    startTime: json['start_time'],
    status: json['status'],
  );

  Map<String, dynamic> toJson() => {
    'id': id,
    'start_date': "${startDate.year.toString().padLeft(4, '0')}-${startDate.month.toString().padLeft(2, '0')}-${startDate.day.toString().padLeft(2, '0')}",
    'start_time': startTime,
    'status': status,
  };
}

我建议做这样的事情:

User.fromJson(Map<String, dynamic> json) {
    try {
      isSocial = json['isSocial'] ?? false;
      loggedIn = json['loggedIn'];
      id = json['id'].toString();
      cookie = json['cookie'];
      username = json['username'];
      nicename = json['nicename'];
      firstName = json['firstName'];
      lastName = json['lastName'];
      name = json['displayname'] ??
          json['displayName'] ??
          '${firstName ?? ''}${(lastName?.isEmpty ?? true) ? '' : ' $lastName'}';

      email = json['email'] ?? id;
      userUrl = json['avatar'], 
      latepointBookings = json['latepoint_bookings']?.map((latepoint_booking) => LatepointBooking.fromJson(latepoint_booking))?.toList() ?? [],
      usermetas = json['usermetas'] ?? {};
    } catch (e) {
      printLog(e.toString());
    }
  }

要点大概就是这一行:

latepointBookings = json['latepoint_bookings']?.map((latepoint_booking) => LatepointBooking.fromJson(latepoint_booking))?.toList() ?? [],

JSON 已经被解析为Map ,因此如果latepoint_bookings存在,它是List<dynamic>类型(或更准确地说是List<Map<String, dynamic>>类型)。 这意味着我们也可以通过利用其fromJson方法有条件地将 map 放入LatepointBooking class 中。 最后一个?? 只需确保永远不会为其分配 null 值。

注意:您可能还需要usermetas ,因为 dart 可能会抱怨它不能直接投射它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM