skip to Main Content

How would one go about decoding a JSON String that looks like this and turn it into a Expansion Tile List with the dropdown of each tile being the "ownerhistory" of each tile:

[
  {
    "bookName": "Harry Potter",
    "Ownerhistory": [
      {
        "name": "Jane",
        "address": "USA",
      },
      {
        "name": "Dan",
        "address": "Russia",
      }
    ]
  },
  {
    "bookName": "Harry Potter",
    "Ownerhistory": [
      {
        "name": "Mary",
        "address": "USA",
      },
      {
        "name": "Ann",
        "address": "Mexico",
      },
      {
        "name": "Molly",
        "address": "Canada",
      }
    ]
  }
]

I pretty much have an idea how to display it, but i could not test it as of the moment since im having a hard time converting the json into a list that i can use to create the widgets

class BookScreen extends ConsumerWidget {
  const BookScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    
    //JSON Arrives here, i already tested this code and confirms that
    //i am recieving the JSON String
    final jsonStringData = ref.watch(responseProvider); //JSON arrives here
    var tagsJson = jsonDecode(jsonStringData);
    //Attempt at converting but throws an error and i have no clue what its doing
    List<dynamic> tags = tagsJson != null ? List.from(tagsJson) : null; 

    return Column(
      children: <Widget>[
        for ( var i in bookList ){ //not currently sure if this is done properly to iterate through the list
          ExpansionTile(
            title: const Text(i.bookName),
            chrildren: <Widgets>[
              for ( var j in i.OwnerHistory)
                ListTile(title: Text(j));;
            ]
          );
        }
      ],
    );
  }
}

2

Answers


  1. I don’t prefer doing serialization & deserialization here , you create another dart file and defining the mechanism for JSON handling , in your case will be:

     import 'dart:convert';
    
    List<LibModel> libModelFromJson(String str) => List<LibModel>.from(json.decode(str).map((x) => LibModel.fromJson(x)));
    
    String libModelToJson(List<LibModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
    
    class LibModel {
        final String bookName;
        final List<Ownerhistory> ownerhistory;
    
        LibModel({
            required this.bookName,
            required this.ownerhistory,
        });
    
        factory LibModel.fromJson(Map<String, dynamic> json) => LibModel(
            bookName: json["bookName"],
            ownerhistory: List<Ownerhistory>.from(json["Ownerhistory"].map((x) => Ownerhistory.fromJson(x))),
        );
    
        Map<String, dynamic> toJson() => {
            "bookName": bookName,
            "Ownerhistory": List<dynamic>.from(ownerhistory.map((x) => x.toJson())),
        };
    }
    
    class Ownerhistory {
        final String name;
        final String address;
    
        Ownerhistory({
            required this.name,
            required this.address,
        });
    
        factory Ownerhistory.fromJson(Map<String, dynamic> json) => Ownerhistory(
            name: json["name"],
            address: json["address"],
        );
    
        Map<String, dynamic> toJson() => {
            "name": name,
            "address": address,
        };
    }
    

    Now you have a list of objects and you can directly use it in your app, guess it would be:

    List<LibModel> yourListVar = libModelFromJson(jsonStringData);
    

    then use the var yourListVar directly when ever and however you want

    Login or Signup to reply.
  2. Try the code below (you can copy & paste to dartpad.dev). But please note that the JSON string in your question is not valid. You need to remove the commas from the lines which are the last in a block, for example "address": "USA", should be "address": "USA". (I did this to test my answer).

    import 'package:flutter/material.dart';
    import 'dart:convert';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
            debugShowCheckedModeBanner: false, home: Scaffold(body: BookScreen()));
      }
    }
    
    class BookScreen extends StatelessWidget {
      const BookScreen({super.key});
    
      @override
      Widget build(BuildContext context) {
        final jsonStringData =
            '[{"bookName":"HarryPotter","Ownerhistory":[{"name":"Jane","address":"USA"},{"name":"Dan","address":"Russia"}]},{"bookName":"HarryPotter","Ownerhistory":[{"name":"Mary","address":"USA"},{"name":"Ann","address":"Mexico"},{"name":"Molly","address":"Canada"}]}]';
    
        final json = jsonDecode(jsonStringData);
    
        List<Map<String, dynamic>> books = json != null ? List.from(json) : [];
    
        return Column(
            children: books
                .map((book) => ExpansionTile(
                    title: Text(book['bookName']),
                    children: book['Ownerhistory']
                        .map<Widget>((owner) => ListTile(
                            title: Text(owner['name']),
                            subtitle: Text(owner['address'])))
                        .toList()))
                .toList());
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search