0

I have this Account class

import 'package:project/models/category_model.dart';

enum AccountTypes {
  cash,
  banks,
}

class Account {
  AccountTypes type;
  double value;
  List<BalnceCategory>? categories;

  Account({
    required this.type,
    required this.value,
    this.categories,
  });

  Map<String, dynamic> toJSON() {
    return {
      "type": type,
      "value": value,
      "categories": categories,
    };
  }
}

Map<AccountTypes, List<dynamic>> accounts = {
  AccountTypes.cash: [
    BalnceCategory(image: "food.png", title: "Food", value: 412.5).toJSON(),
    BalnceCategory(image: "shopping.png", title: "Shopping", value: 412.5).toJSON(),
  ],
  AccountTypes.banks: [
    BalnceCategory(image: "food.png", title: "Food", value: 1242.63).toJSON(),
    BalnceCategory(image: "shopping.png", title: "Shopping", value: 1242.63).toJSON(),
  ]
};

each Account should contain a list of BalnceCategory

class BalnceCategory {
  String image;
  String title;
  double value;

  BalnceCategory({
    required this.image,
    required this.title,
    required this.value,
  });

  Map<String, dynamic> toJSON() {
    return {
      "image": image,
      "title": title,
      "value": value,
    };
  }
}

Now I want to display this Map Map<AccountTypes, List<dynamic>> accounts in two sections...I will refer to this map as accounts. So in the first section I want to list all available accounts in something like a Row with a button for each account, so what I did is I mapped through accounts like this accounts.entries.map and returned a button for each account, and these buttons can set a state called currentIndex with it's index.

Now in the second section I want to list all accounts categories depending on the currentIndex state value, so for example if the currentIndex value is 0 I want to display all the categories in cash account, and if the currentIndex value is 1 I want to display all the categories in banks account.

So far all I am done the buttons section and I it is working properly and my problem is in the second section. I tried to do this

Expanded(
  child: GridView.builder(
    physics: const BouncingScrollPhysics(),
    gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 2,
      mainAxisSpacing: mainUnit / 2,
      crossAxisSpacing: mainUnit / 2,
      childAspectRatio: 3 / 4,
    ),
    itemCount: accounts.keys.length,
    itemBuilder: (context, index) {
      return accounts.forEach((key, value) {
        if (key.index == currentIndex) {
          value.map((e) => {Text(e.toString())});
        }
      });
    },
  ),
),

but it gives me this error: The return type 'void' isn't a 'Widget', as required by the closure's context.

1 Answers1

0

The ItemBuilder should return a widget, you return accounts.forEach(...) that is a void function ( forEach() is a void function/closure).

Try this:

  Text(  accounts.keys.firstWhere( (item) => item.index == currentIndex,
orElse: ()=> "",).toString() );

BUT!!!! Wait a moment!!!!! Why don't you take a look at https://pub.dev/packages/flutter_sticky_header

You should implement what you need: it displays an header that, in your case, could be a string AccountTypes.cash.toString() or AccountTypes.banks.toString(), and then follow the example and you should obtain what you need ( display grouped cards for AccountTypes ). more over I suggest you to use

https://pub.dev/packages/freezed

It helps you to defined your data class, and to Serialize then to JSON.

For Example:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'account.g.dart';
part 'account.freezed.dart';

@freezed()
class Account with _$Account {

factory Account.cash({
   @Default(0) double? value;
   List<BalnceCategory>? categories;
 }) = CashAccount;

factory Account.bank({
   @Default(0) double? value;
   List<BalnceCategory>? categories;
}) = BankAccount;


 factory Account.fromJson(Map<String, dynamic> json) =>
    _$AccountFromJson(json);
  
}

In that manner you have your data class ( account ) with its type ( cash / bank ) and serializable.

To create an account it is easy :

 var myCash = Account.cash(... , ... );

Both CashAccount and BankAccount are two different classes that implement Account ( abstract class ), you can use it in a simple list of Accounts. then , to chack for bank/cash you can use:

var myAccount = Account.cash(....);

 myAccount.when(
    bank: (BankAccount account) =>  ....,
    cash: (CashAccount account) =>  .... ,
  ),
Mike
  • 335
  • 1
  • 8
  • I returned `AccountTypes.cash` twice. and when I change the `currentIndex` it updates the `AccountType`, but I want to display all the categories in this map `Map> accounts` in a GirdView –  Nov 09 '22 at 17:22
  • Ok, I will give it a try. Thanks for your efforts –  Nov 09 '22 at 18:02