首页 > 解决方案 > 类型错误问题将对象列表从 Json 转换为类结构

问题描述

我正在尝试将对象列表从 JSON 转换为类结构。我遇到了一些我似乎无法解决的类型错误。

我已经设置了一些方法来将每个对象转换为 JSON 和从 JSON 转换,并且它们单独工作得很好,我没有遇到任何问题。问题是当我尝试将所有部分放在一起时。

我的代码出现错误的地方:

    var temp = json.decode(response.body);
    var shifts = ShiftList.fromJson(temp); // This is where it breaks

移位列表类:

   class ShiftList {
  List<Shift> shifts;
  ShiftList({
    this.shifts,
  });

  addShift(Shift shift){
    if(shifts == null){
      shifts = [shift];
    }else{
      shifts.add(shift);
    }
  }

  factory ShiftList.fromJson(Map<String, dynamic> json) {
    return ShiftList(
      shifts: _toObjectList(json['Shifts'], (e) => Shift.fromJson(e)),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'Shifts': _fromList(shifts, (e) => e.toJson()),
    };
  }

}

List _fromList(data, Function(dynamic) toJson) {
  if (data == null) {
    return null;
  }
  var result = [];
  for (var element in data) {
    var value;
    if (element != null) {
      value = toJson(element);
    }
    result.add(value);
  }
  return result;
}

List<T> _toObjectList<T>(data, T Function(Map<String, dynamic>) fromJson) {
  if (data == null) {
    return null;
  }
  var result = <T>[];
  for (var element in data) {
    T value;
    if (element != null) {
      value = fromJson(element as Map<String, dynamic>);
    }
    result.add(value);
  }
  return result;
}

班次:

class Shift {
  String Name;
  String AccountID;
  String Identifier;
  UserList UserVal;
  ReportList Reports;
  TaskList Tasks;
  String Scheduling;
  String ShiftManagerCode;

  Shift({
    this.AccountID,
    this.Name,
    this.ShiftManagerCode,
    this.Identifier,
    this.UserVal,
    this.Reports,
    this.Tasks,
    this.Scheduling,
  });

  factory Shift.fromJson(Map<String, dynamic> json) {
    return Shift(
      AccountID: json['AccountID'] as String,
      Identifier: json['Identifier'] as String,
      Name: json['ShiftName'] as String,
      ShiftManagerCode: json['ShiftManagerCode'] as String,
      UserVal: json['UserVal'] as UserList,
      Reports: json['Reports'] as ReportList,
      Tasks: json['Tasks'] as TaskList,
      Scheduling: json['Scheduling'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'ShiftName': this.Name,
      'AccountID': this.AccountID,
      'Identifier': this.Identifier,
      'ShiftManagerCode': this.ShiftManagerCode,
      'UserVal': this.UserVal,
      'Reports': this.Reports,
      'Tasks': this.Tasks,
      'Scheduling': this.Scheduling,
    };
  }
}

最后,出现错误的 UserList 类:

class UserList {
  List<UserObject> users;
  UserList({
    this.users,
  });

  addUser(UserObject user){
    if(users == null){
      users = [user];
    }else{
      users.add(user);
    }
  }

  factory UserList.fromJson(Map<String, dynamic> json) {
    return UserList(
      users: _toObjectList(json['UserVal'], (e) => UserObject.fromJson(e)),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'UserVal': _fromList(users, (e) => e.toJson()),
    };
  }

}

List _fromList(data, Function(dynamic) toJson) {
  if (data == null) {
    return null;
  }
  var result = [];
  for (var element in data) {
    var value;
    if (element != null) {
      value = toJson(element);
    }
    result.add(value);
  }
  return result;
}

List<T> _toObjectList<T>(data, T Function(Map<String, dynamic>) fromJson) {
  if (data == null) {
    return null;
  }
  var result = <T>[];
  for (var element in data) {
    T value;
    if (element != null) {
      value = fromJson(element as Map<String, dynamic>);
    }
    result.add(value);
  }
  return result;
}

我希望它将 JSON 对象放入我已有的类结构中。我得到的具体错误如下:

flutter: type 'List<dynamic>' is not a subtype of type 'UserList' in typecast

我的第一个代码片段中的变量 temp 如下:

{
    "Shifts": [
        {
            "UserVal": [
                {
                    "UID": "test",
                    "Email": "test@gmail.com",
                    "Phone": "0000000000",
                    "Name": "James"
                },
                {
                    "UID": "test",
                    "Email": "test@gmail.com",
                    "Phone": "0000000000",
                    "Name": "Jacob"
                }
            ],
            "AccountID": "1295",
            "Identifier": "JhfSC",
            "ShiftManagerCode": "15A4",
            "Reports": [
                {
                    "Quantity": "3",
                    "User": "Jacob",
                    "Supplies": "ItemA",
                    "Subject": "Supplies",
                    "Note": "test"
                }
            ],
            "Scheduling": "EMPTY",
            "ShiftName": "AF 37",
            "Tasks": [
                {
                    "Status": "done",
                    "User": "James",
                    "Description": "Description here",
                    "Name": "TaskName here"
                }
            ]
        }
    ]
}

标签: jsondynamicflutterdarttypeerror

解决方案


而不是创建包含您的列表的新对象,只需让您的班次类包含列表的属性。

class Shift {
  String Name;
  String AccountID;
  String Identifier;
  List<UserObject> UserVal;
  ReportList Reports; // do same for this
  TaskList Tasks; // do same for this
  String Scheduling;
  String ShiftManagerCode;

  Shift({
    this.AccountID,
    this.Name,
    this.ShiftManagerCode,
    this.Identifier,
    this.UserVal,
    this.Reports,
    this.Tasks,
    this.Scheduling,
  });

  factory Shift.fromJson(Map<String, dynamic> json) {
    return Shift(
      AccountID: json['AccountID'] as String,
      Identifier: json['Identifier'] as String,
      Name: json['ShiftName'] as String,
      ShiftManagerCode: json['ShiftManagerCode'] as String,
      UserVal: json['UserVal'] == null ? List<UserObject> : (json['UserVal'] as List<Dynamic>).map((dynamic map) => UserObject.fromJson(map)).toList(),
      Reports: json['Reports'] as ReportList,
      Tasks: json['Tasks'] as TaskList,
      Scheduling: json['Scheduling'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'ShiftName': this.Name,
      'AccountID': this.AccountID,
      'Identifier': this.Identifier,
      'ShiftManagerCode': this.ShiftManagerCode,
      'UserVal': this.UserVal,
      'Reports': this.Reports,
      'Tasks': this.Tasks,
      'Scheduling': this.Scheduling,
    };
  }
}

所以现在你可以直接在你的 Json 中进行转换。您必须在 toJson 中做额外的工作才能正确映射它。


推荐阅读