如果没有名称/键,如何在Flutter / Dart中序列化/解析嵌套的JSON数组

时间:2019-05-03 00:00:18

标签: json parsing serialization dart flutter

我正在使用一个RESTful API,该API似乎可以正常工作并在其他应用程序中使用,这给了我类似的东西:

 "notes": [
    [
      {
        "automaticNote": false,
        "contactId": 0,
        "caseFileId": 0,
        "dateCreated": "2019-05-02",
        "deletedTime": "2019-05-02T19:31:54.588Z"
      }
    ]
  ]

双方括号表示一对方括号没有与之关联的名称/键。更糟糕的是,notes本身嵌套在一些复杂的JSON中。

我尝试使用JSON to Dart,但会引发错误。所以,实际上我的问题是,如何序列化没有键/名称的JSON数组?

我通常会这样:

    class Note {
  bool automaticNote;
  int contactId;
  int caseFileId;
  String dateCreated;
  String deletedTime;

  Note(
      {this.automaticNote,
      this.contactId,
      this.caseFileId,
      this.dateCreated,
      this.deletedTime});

  Note.fromJson(Map<String, dynamic> json) {
    automaticNote = json['automaticNote'];
    contactId = json['contactId'];
    caseFileId = json['caseFileId'];
    dateCreated = json['dateCreated'];
    deletedTime = json['deletedTime'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['automaticNote'] = this.automaticNote;
    data['contactId'] = this.contactId;
    data['caseFileId'] = this.caseFileId;
    data['dateCreated'] = this.dateCreated;
    data['deletedTime'] = this.deletedTime;
    return data;
  }
}

但是双重JSON数组使我失望(同样,notes本身嵌套在一个更复杂的JSON对象中,但是为了简单起见,我在这里没有包括全部内容)。

谢谢!

3 个答案:

答案 0 :(得分:1)

解码后,notes通常是某些Map<String, dynamic>的成员。我们称之为m

所以m['notes']是一个列表,第一位成员,m['notes'][0]也是一个列表。它的第一个成员m['notes'][0][0]是另一个Map<String, dynamic>,这是构造函数所需要的。

因此,您应该可以使用:

Note n = Note.fromJson(m['notes'][0][0]);

答案 1 :(得分:1)

  
    

但是双重JSON数组让我失望...

  

使用哪个元素数组都没有关系。 正确声明数据模型很重要。

import 'dart:convert';

import 'json_objects.dart';

void main() {
  var map = jsonDecode(_json) as Map;
  var response1 = Response1.fromJson(map);
  for (var list1 in response1.notes) {
    for (var note in list1) {
      print(note.dateCreated);
      print(note.deletedTime);
    }
  }
}

var _json = '''
{
  "notes": [
    [
      {
        "automaticNote": false,
        "contactId": 0,
        "caseFileId": 0,
        "dateCreated": "2019-05-02",
        "deletedTime": "2019-05-02T19:31:54.588Z"
      }
    ]
  ]
}''';

示例的模型声明:

// Generated by 'yaml2podo'
// Version: 0.1.11
// https://pub.dev/packages/yaml2podo

class Response1 {
  final List<List<Response1Notes>> notes;

  Response1({this.notes});

  factory Response1.fromJson(Map map) {
    return Response1(
        notes: _toList(map['notes'],
            (e) => _toList(e, (e) => Response1Notes.fromJson(e as Map))));
  }

  Map<String, dynamic> toJson() {
    var result = <String, dynamic>{};
    result['notes'] = _fromList(notes, (e) => _fromList(e, (e) => e.toJson()));
    return result;
  }
}

class Response1Notes {
  final int contactId;
  final bool automaticNote;
  final int caseFileId;
  final DateTime deletedTime;
  final DateTime dateCreated;

  Response1Notes(
      {this.contactId,
      this.automaticNote,
      this.caseFileId,
      this.deletedTime,
      this.dateCreated});

  factory Response1Notes.fromJson(Map map) {
    return Response1Notes(
        contactId: map['contactId'] as int,
        automaticNote: map['automaticNote'] as bool,
        caseFileId: map['caseFileId'] as int,
        deletedTime: _toDateTime(map['deletedTime']),
        dateCreated: _toDateTime(map['dateCreated']));
  }

  Map<String, dynamic> toJson() {
    var result = <String, dynamic>{};
    result['contactId'] = contactId;
    result['automaticNote'] = automaticNote;
    result['caseFileId'] = caseFileId;
    result['deletedTime'] = _fromDateTime(deletedTime);
    result['dateCreated'] = _fromDateTime(dateCreated);
    return result;
  }
}

String _fromDateTime(dynamic data) {
  if (data == null) {
    return null;
  }
  if (data is DateTime) {
    return data.toIso8601String();
  }
  return data as String;
}

List _fromList(dynamic data, dynamic 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;
}

DateTime _toDateTime(dynamic data) {
  if (data == null) {
    return null;
  }
  if (data is String) {
    return DateTime.parse(data);
  }
  return data as DateTime;
}

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

/*
Response1:
  "notes": List<List<Response1Notes>>

Response1Notes:
  "automaticNote": bool
  "contactId": int
  "caseFileId": int
  "dateCreated": DateTime
  "deletedTime": DateTime
*/

答案 2 :(得分:1)

让我们以自动保存为例;

automaticNote = json ['notes'] [0] [0] ['automaticNote'];

这为注释提供了密钥,该注释具有一个数组,您的数据在该数组的第一个点或索引为0(注释的值因此为[0]),并且该数组内还有另一个数组,该数组包含您的数据。再次,它是第一个数组项,所以[0],然后您最终处于数据级别,因此您可以将键用于autoNote ['automaticNote']。

Note.fromJson(Map<String, dynamic> json) {
    automaticNote = json[0][0]['automaticNote'];
    contactId = json[0][0]['contactId'];
    caseFileId = json[0][0]['caseFileId'];
    dateCreated = json[0][0]['dateCreated'];
    deletedTime = json[0][0]['deletedTime'];
  }