Home > Mobile >  Dart: TypeError: item.get$balance is not a function
Dart: TypeError: item.get$balance is not a function

Time:12-12

I have a class as below:

class Account {
  Account({
    required this.balance,
  });
  late final double balance;  
  Account.fromJson(Map<String, dynamic> json){
    balance= json['balance'];
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    _data['balance'] = balance;
    return _data;
  }
}

I have an array of this Account class. To calculate total of the balances of accounts I did:

double total = accounts.fold(0, (sum, item) => sum   item.balance);

Running this code I get this error:

Uncaught TypeError: item.get$balance is not a function

UPDATE:

This is a sample code to test on DartPad:

import 'dart:convert';

void main() {
  String jsonStr = '[{"balance":20.5},{"balance":20.5}]';
  
//   Not working
//   List<Account> accounts = List.from(json.decode(jsonStr));
//   double total = accounts.fold(0, (sum, item) => sum   item.balance);
//   print(total);

//   Works fine
//   Account account = Account(balance: 20.5);
//   List<Account> accounts2 = [account, account];
//   double total = accounts2.fold(0, (sum, item) => sum   item.balance);
//   print(total); 
  
//  Works fine
    List<Account> accounts3 = List<Account>.from(json.decode(jsonStr)
          .map((model) => Account.fromJson(model)));
    double total = accounts3.fold(0, (sum, item) => sum   item.balance);
    print(total);  
}

class Account {
  Account({
    required this.balance,
  });
  
  late final double balance;  
  
  Account.fromJson(Map<String, dynamic> json){
    balance= json['balance'];
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    _data['balance'] = balance;
    return _data;
  }
}

Now my question is what is the differences first and last approaches?

CodePudding user response:

Should try this, I think you got issue with the list type declaration

void main() {
  String jsonStr = '[{"balance":20.5},{"balance":20.5}]';
  AccountList accounts = AccountList.fromJsonMap(json.decode(jsonStr));
  double total = accounts.accounts!.fold(0, (sum, item) => sum   item.balance);
  print(total);
}
class Account {
  Account({
    required this.balance,
  });
  late final double balance;  
  Account.fromJson(Map<String, dynamic> json){
    balance= json['balance'];
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    _data['balance'] = balance;
    return _data;
  }
}

updated answer

import 'dart:convert';

void main() {
  String jsonStr = '[{"balance":20.5},{"balance":20.5}]';
  AccountList accounts = AccountList.fromJsonMap(json.decode(jsonStr));

  double totalValue = 0;
  for (var item in accounts.accounts!) {
    totalValue  = item.balance;
  }
 
  print(totalValue);
}

class AccountList {
  List<Account>? accounts;
  AccountList.fromJsonMap(dynamic data)
      : accounts = List<Account>.from(data.map((it) => Account.fromJson(it)));
}

class Account {
  Account({
    required this.balance,
  });
  late final double balance;
  Account.fromJson(Map<String, dynamic> json) {
    balance = json['balance'];
  }

  Map<String, dynamic> toJson() {
    final _data = <String, dynamic>{};
    _data['balance'] = balance;
    return _data;
  }
}

CodePudding user response:

void main() {
  final accounts = [Account(balance: 5), Account(balance: 3)];
  double total = accounts.fold(0, (sum, item) => sum   item.balance);
  print(total); // Prints 8
}

It works. Are you sure accounts is the correct type? Did you properly load the JSON for all of its elements?

Edit

The issue is not with the fold. This will work:

void main() {
  String jsonStr = '[{"balance":20.5},{"balance":20.5}]';
  List accountsMap = List.from(jsonDecode(jsonStr));
  List<Account> accounts = accountsMap.map((item) => Account.fromJson(item)).toList();
  double total = accounts.fold(0, (sum, item) => sum   item.balance);
  print(total); // Prints 41
}

The issue is with decoding into a List of Map, which is not the same of decoding into a List of Account.

You can use the code above, or, even better, follow the answer of Jahidul Islam.

CodePudding user response:

Try adding a getter method inside Account:

double get balance => balance;

CodePudding user response:

Your fold function looks okay. Change your API function

      Future<List<Account?>?> getAllAccounts() async {
        try {
          final response = await ...;
    
          List<Account?>? allAccounts = [];
          
          final results = List<Map<String, dynamic>>.from(jsonDecode(response.data));
    
          allAccounts = results.map((data) => Account.fromJson(data)).toList();
          
          return allAccounts;
        } catch (error) {
          print('handle API errors');
          return [];
        }
      }

// get Balance from anywhere

double getTotalBalance() async {
    List<Account?>? accounts = await getAllAccounts();
    
    return (accounts??[]).fold(0, (sum, item) => sum   (item?.balance??0));
}
  • Related