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));
}