skip to Main Content

I have a list like this:

List<ProductModel> productList = [
    ProductModel(name: "Oranges", date: "2023-05-01"),    
    ProductModel(name: "Apples", date: "2023-05-01"),
    ProductModel(name: "Kiwis", date: "2023-03-01"),
];

I would like to group the items by date using groupBy and display it in Widget build as so:

2023-05-01:
Oranges
Apples

2023-03-01:
Kiwis

I have already done the grouping in a list and when printed my groupByDate list looks like so:

{2023-05-01: [Instance of 'ProductModel', Instance of 'ProductModel'], 2023-03-01: [Instance of 'ProductModel']}

Now, the question is how do I use ListView.builder to display the list items in build method:

class ProductListPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _ProductListPageState();
}

class _ProductListPageState extends State<ProductListPage> {
  late StreamController<int> _postsController;
  var groupByDate;

  @override
  void initState() {
    _postsController = new StreamController();
    getProducts();
    super.initState();
  }

  void getProducts() {
    Fetch.getProdcuts().then((value) => {
      _postsController.add(1);
      
      List<ProductModel> productList = [];

      for (var item in value!) {    
         final encode = json.encode(item.toJson());
         final product = ProductModel.fromJson(jsonDecode(encode));
         productList.add(product);
      }    
      groupByDate = groupBy(productList, (obj) => (obj! as ProductModel).date);

    });
  }

  @override
    Widget build(BuildContext context) {            
      return Scaffold(
        body: ListView.builder(
            itemCount: groupByDate.length,
            itemBuilder: (context, index) {
              final key = groupByDate.keys.elementAt(index);
              final values = groupByDate.values.elementAt(index);
              return Column(
                children: [
                   Text("$key"),
                   Column(
                     children: [
                       //How do I show the list with values here??? 
                       entry.value.map((e) => Text(e.name)).toList(),
                   ])
              ])
            }
        )
      );
    }

class ProductModel extends Object {
  String? name;
  String? date;

  ProductModel({this.name, this.date});

  ProductModel.fromJson(Map<String, dynamic> json) {
    name = json["name"];
    date = json["date"];
  }

  Map<String, dynamic> toJson() => {
    'name': name,
    'date': date,
  };
}

2

Answers


  1. All you have to do is define your groupByDate variable as Map. Instead of just

    var groupByDate;
    

    change that to

    var groupByDate = <String, List<ProductModel>>{};
    

    so the compiler would know it’s a map.

    Edit. Upon question clarification, here’s how you show the list of grouped values

     ListView.builder(
            itemCount: groupByDate.length,
            itemBuilder: (context, index) {
              final key = groupByDate.keys.elementAt(index);
              final values = groupByDate.values.elementAt(index);
              return Column(children: [
                Text("$key"),
                for (var item in values)
                Text("${item.name}"),
              ]);
            })
    
    Login or Signup to reply.
  2. You need to use groupByDate.entries to get a list of entries in a Map, that way you will have access to both key & value:

    @override
    Widget build(BuildContext context) {
      return Scaffold(
          body: ListView.builder(
              itemCount: groupByDate.length,
              itemBuilder: (context, index) {
                final entry = groupByDate.entries.elementAt(index);
                return Column(children: [
                  Text(entry.key ??
                      ''), 
                  Column(
                    children: entry.value.map((e) => Text(e.name ?? '')).toList(),
                  )
                ]);
              }));
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search