Parse complex JSON into List Flutter

Issue

I have a json file like this which I stored in the asset:

[
    {
        "topic":"Title One",
        "subTopic":
        [
            "Overview",
            "Install",
            "Start"
        ]
    },
    {
        "topic":"Title Two"
    },
    {
        "topic":"Title Three",
        "subTopic":
        [
            "Overview",
            "Emulation",
            "2. Install"
        ]
    },
    {
        "topic":"Title Four",
        "subTopic":
        [
            "Overview",
            "Start",
            "3. Try"
        ]
    }
]  

Which has an array and inside it also has array. I wonder how can I parse the "subTopic" as List and displayed it. My class:

class File {
  String topic;
  List<String> subTopic;

  File({this.topic, this.subTopic});

  File.fromJson(Map<String, dynamic> json) {
    topic = json['topic'];
    subTopic = json['subTopic'];
  }

  Map<String, dynamic> toJson() => {
        'topic': topic,
        'subTopic': subTopic,
      };
}

What i did in maint.dart:

class MyHomePage extends StatelessWidget {
  Future<List<File>> getData() async {
    String response = await rootBundle.loadString('file.json');
    return await Future.delayed(Duration(seconds: 2), () {
      List<dynamic> data = jsonDecode(response);
      //Iterate over list and map each object in list
      List<File> files=
          data.map((data) => File.fromJson(data)).toList();
      return files;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text("File"),
        ),
        body: Container(
          child: FutureBuilder<List<File>>(
              future: getData(),
              builder: (context, data) {
                if (data.connectionState != ConnectionState.waiting &&
                    data.hasData) {
                  var fileList = data.data;
                  return Drawer(
                    child: ListView.builder(
                        itemCount: fileList.length,
                        itemBuilder: (context, index) {
                          var fileData = fileList[index];
                          return ExpansionTile(
                            // key: Key("$index"),
                            // title: Text(fileData.topics?? ""),
                            children: <Widget>[
                              Container(
                                width: double.infinity,
                                child: Padding(
                                  padding: const EdgeInsets.all(20.0),
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: <Widget>[
                                      //I want to display the list of subTopic here
                                    ],
                                  ),
                                ),
                              )
                            ],
                          );
                        }),
                  );
                } else {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                }
              }),
        ),
      ),
    );
  }
}

I want to displayed the list of subtopic in the listView. How can I do this? Thanks in advance!

Solution

It is quite easy you can cast your json['subtype'] as an Iterable to generate a new List<String> object.

Code:

List<String>.from(json['subTopic'] as Iterable)

Full Sample:

class File {
  String topic;
  List<String> subTopic;

  File({this.topic, this.subTopic});

  File.fromJson(Map<String, dynamic> json) {
    topic = json['topic'];
    subTopic = List<String>.from(json['subTopic'] as Iterable);
  }

  Map<String, dynamic> toJson() => {
        'topic': topic,
        'subTopic': subTopic,
      };
}

Answered By – Guillaume Roux

Answer Checked By – Jay B. (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.