繁体   English   中英

未处理的异常:将 object 转换为可编码的 object 失败:“日期时间”实例

[英]Unhandled Exception: Converting object to an encodable object failed: Instance of 'DateTime'

我有一个任务的 Model =>

class Task {


Task({this.isDone,this.name,this.time,this.priorityValue});
  final String name;
   bool isDone;
   final DateTime time;
   int priorityValue;



 factory Task.fromJson(Map<String, dynamic> jsonData) {
    return Task(
      name: jsonData['name'],
      isDone: false,
      time: jsonData['time'],
      priorityValue: jsonData['priorityValue'],
    );
  }

  toJSONEncodable() {
    Map<String, dynamic> m = new Map();

    m['name'] = name;
    m['isDone'] = isDone;
    m['time'] = time;
    m['priorityValue'] = priorityValue;

    return m;
  }

  static Map<String, dynamic> toMap(Task task) => {
        'name': task.name,
        'isDone': task.isDone,
        'time': task.time,
        'priorityValue': task.priorityValue,
      };
}

当使用 localStorage package 来保存一些对象列表时,我得到了这个错误 =>

(颤振)未处理的异常:将 object 转换为可编码的 object 失败:“日期时间”实例

_saveToStorage() {
storage.setItem('tasks', list.toJSONEncodable());
print("Saved");

}

我尝试使用.toString() 但后来我得到这个错误=> type 'String' is not a subtype of type 'int' of 'index'

在 LocalStorage package 上保存日期时间的任何想法?

更新:

factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
  name: jsonData['name'],
  isDone: false,
  time: jsonData["time"] == null ? null : DateTime.parse(jsonData["time"]),
  priorityValue: jsonData['priorityValue'],
);


 }

  toJSONEncodable() {
Map<String, dynamic> m = new Map();

m['name'] = name;
m['isDone'] = isDone;
m['time'] = time == null ? null : time.toIso8601String();
m['priorityValue'] = priorityValue;

return m;


 }

static Map<String, dynamic> toMap(Task task) => {
    'name': task.name,
    'isDone': task.isDone,
    'time': task.time,
    'priorityValue': task.priorityValue,
  };


var items = storage.getItem('tasks');
            if (items != null) {
              list.items = List<Task>.from(
                (items as List).map(
                  (item) => Task(
                    name: item['name'],
                    isDone: item['isDone'],
                    time: DateTime.parse(item['time']),
                    priorityValue: items['priorityValue'],
                  ),
                ),
              );
            }

更新后我收到此错误“类型'String'不是'index'类型'int'的子类型”

更新2:

var items = storage.getItem('tasks');

            if (items != null) {
              final decodedJson = jsonDecode(items);
              list.items = (decodedJson as List)
                  .map((e) => Task.fromJson(e))
                  .toList();
              final task = list.items.first;
              print("${task.name}");
              // list.items = List<Task>.from(
              //   (items as List).map(
              //     (item) => Task(
              //       name: item['name'],
              //       isDone: item['isDone'],
              //       time: DateTime.parse(item['time']),
              //       priorityValue: items['priorityValue'],
              //     ),
              //   ),
              // );
            }

第二次更新后我得到“类型'_InternalLinkedHashMap<String,动态>'不是'String'类型的子类型”

固定的

我将 DaeTme 更改为 model 中的字符串,并在得到它时将时间转换为字符串

"${selectedDate.toLocal()}".split(' ')[0]

使用 toJson

"changeDate": changeDate == null? null: changeDate.toIso8601String(),

和来自Json

changeDate: json["changeDate"] == null? null: DateTime.parse(json["changeDate"]),

我强烈建议您使用Retrofitjson_serializable来描述您的 API

它可能看起来像这样:

import 'package:json_annotation/json_annotation.dart';

part 'task.g.dart';

@JsonSerializable(nullable: false, explicitToJson: true)
class Task {
  final String name;
  bool isDone;
  final DateTime time;
  int priorityValue;

  Task({this.isDone, this.name, this.time, this.priorityValue});

  factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);

  Map<String, dynamic> toJson() => _$TaskToJson(this);
}

之后,您需要运行build_runner
flutter pub run build_runner build

它会毫无痛苦地为您生成toJsonfromJson方法:

Task _$TaskFromJson(Map<String, dynamic> json) {
  return Task(
    isDone: json['isDone'] as bool,
    name: json['name'] as String,
    time: DateTime.parse(json['time'] as String),
    priorityValue: json['priorityValue'] as int,
  );
}

Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
      'name': instance.name,
      'isDone': instance.isDone,
      'time': instance.time.toIso8601String(),
      'priorityValue': instance.priorityValue,
    };

您可以查看测试:

void main() {
  test('Task should be parsed from json', () {
    const json = '''
    [
      {
        "name": "testing",
        "isDone": false,
        "time": "2021-01-12T13:57:10.705476",
        "priorityValue": 0
      }
    ]
    ''';

    final List decodedJson = jsonDecode(json);
    final List<Task> list = decodedJson.map((e) => Task.fromJson(e)).toList();

    final Task task = list.first;

    expect(task.name, 'testing');
    expect(task.isDone, false);
    expect(task.time, DateTime.parse("2021-01-12T13:57:10.705476"));
    expect(task.priorityValue, 0);
  });
}

暂无
暂无

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

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