Home > Software engineering >  Nested lists in json to objects
Nested lists in json to objects

Time:12-04

I have this asset json file, with nested lists. I was trying to turn them into a list of objects. Note this json file is extremely simplified and the original file contains thousands of sections, so editing the file is not an option.

>    {
>         "code": 200,
>         "status": "OK",
>         "Daily": [
>             {
>                 "id": 1,
>                 "title": "First page",
>                 "children": [
>                     {
>                         "id": 1,
>                         "title": "Section one",
>                         "children": [
>                             {
>                                 "id": 1,
>                                 "case1": "case 1",
>                                 "case2": "case 2",
>                                 "ref": "ref 1"
>                             },
>                             {
>                                 "id": 2,
>                                 "case1": "case 1",
>                                 "english": "case 2",
>                                 "ref": "ref 2"
>                             }
>                         ]
>                     },
>                     {
>                         "id": 2,
>                         "title": "Section two",
>                         "children": [
>                             {
>                                 "id": 1,
>                                 "case1": "case 1",
>                                 "case2": "case 2",
>                                 "ref": "ref 1"
>                             },
>                             {
>                                 "id": 2,
>                                 "case1": "case 1",
>                                 "english": "case 2",
>                                 "ref": "ref 2"
>                             }
>                         ]
>                     }
>                 ]
>             }
>         ]
>     }

What I have tried:

class DailyModel {
  int id;
  String title;
  List<Sections> children;
  DailyModel({
    required this.id,
    required this.title,
    required this.children,
  });

  factory DailyModel.fromJson(Map<String, dynamic> json) {
    return DailyModel(
        id: json["id"], title: json["title"], children: json["children"]);
  }
}

class Sections {
  int id;
  String title;
  List<Cases> children;
  Sections({
    required this.id,
    required this.title,
    required this.children,
  });

  factory Sections.fromJson(Map<String, dynamic> json) {
    return Sections(
        id: json["id"], title: json["title"], children: json["children"]);
  }
}

class Cases {
  int id;
  String case1;
  String case2;
  String ref;
  Cases({
    required this.id,
    required this.case1,
    required this.case2,
    required this.ref,
  });

  factory Cases.fromJson(Map<String, dynamic> json) {
    return Cases(
        id: json["id"],
        case1: json["case1"],
        case2: json["case2"],
        ref: json["ref"]);
  }
}

Then calling them like so:

Future<List<DailyModel>> getSections(BuildContext context) async {
  String data =
      await DefaultAssetBundle.of(context).loadString("assets/sections.json");
  List jsonResponse = json.decode(data)["Daily"];
  return jsonResponse.map((data) => new DailyModel.fromJson(data)).toList();
}

But I get this error:

'List<dynamic>' is not a subtype of type 'List<Sections>'

I have also tried adding a List sections variable in the class sections: json["children"]["title"] but that needs an index which is not suitable for my usecase

CodePudding user response:

You need to actually convert the List that's the JSON child into a list of the underlying class, which you can do with a map. (There's no need for the named parameters, so I removed them. Feel free to add back if you like.) Note that your JSON doesn't always include "case2" so that can be null.

class DailyModel {
  int id;
  String title;
  List<Section> children;

  DailyModel(
    this.id,
    this.title,
    this.children,
  );

  factory DailyModel.fromJson(Map<String, dynamic> json) {
    return DailyModel(
      json['id'],
      json['title'],
      json['children']
          .map<Section>((section) => Section.fromJson(section))
          .toList(),
    );
  }
}

class Section {
  int id;
  String title;
  List<Case> children;

  Section(
    this.id,
    this.title,
    this.children,
  );

  factory Section.fromJson(Map<String, dynamic> json) {
    return Section(
      json['id'],
      json['title'],
      json['children']
          .map<Case>((caseItem) => Case.fromJson(caseItem))
          .toList(),
    );
  }
}

class Case {
  int id;
  String case1;
  String? case2;
  String ref;

  Case(
    this.id,
    this.case1,
    this.case2,
    this.ref,
  );

  factory Case.fromJson(Map<String, dynamic> json) {
    return Case(
      json['id'],
      json['case1'],
      json['case2'],
      json['ref'],
    );
  }
}

Use it as before.

  final data = json.decode(asset)['Daily'];
  final list = data.map((dailyItem) => DailyModel.fromJson(dailyItem)).toList();

CodePudding user response:

Add this model:

class ResponseModel{
int code;
String status;
List<DailyModel> Daily;
//add fromJson method
...
}
  • Related