Reputation: 1
I am trying to get the following json into a data table (CFTable). The json is in the structure of map>. I have the COA class that will take care of the inner map (Map), and a TransposedCF class to make a map from that (Map). I dont want to hard code the string keys for the outer map ("Acquisition", "BP Uplift"...etc) or the inner map ("2019", "2020"...etc) because that will constantly change. I'm having difficulty with the fromJson method for the TransposedCF class (hence the ?).
Also, after I build this class I would like to consume it in a table, but there are many errors there...
JSON:
{
"Acquisition": {
"2019": -78600000,
"2020": 0,
"2021": 0,
"2022": 0,
"2023": 0,
"2024": 0,
"2025": 0,
"2026": 0,
"2027": 0,
"2028": 0,
"2029": 0,
"2030": 77527013.89465855
},
"BP Uplift": {
"2019": 0,
"2020": 0,
"2021": 0,
"2022": 0,
"2023": 0,
"2024": 0,
"2025": 0,
"2026": 0,
"2027": 0,
"2028": 0,
"2029": 0,
"2030": 0
},
"Capex": {
"2019": 0,
"2020": 0,
"2021": 0,
"2022": 0,
"2023": 0,
"2024": 0,
"2025": 0,
"2026": 0,
"2027": 0,
"2028": 0,
"2029": 0,
"2030": 0
}
}
FLUTTER:
import 'package:flutter/material.dart';
class COA {
final Map<String, double> values;
const COA({@required this.values});
factory COA.fromJson(Map json) {
final values = json['values'];
return COA(values: values);
}
}
class TransposedCF {
final String assetname;
final Map<String, COA> coas;
TransposedCF({this.assetname, this.coas});
factory TransposedCF.fromJson(String name, List json) {
return TransposedCF(
assetname: name,
coas: ?,
);
}
}
class CFTable extends StatelessWidget {
final TransposedCF cf;
CFTable({Key key, this.cf}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text("OGANICA"),
DataTable(columns: _buildColumns(), rows: _buildDataRows()),
],
);
}
List<DataColumn> _buildColumns() {
final years = cf.coas.first.values.keys.toList()..sort();
return [
DataColumn(label: Text(cf.assetname)),
for (String year in years) DataColumn(label: Text("$year"))
];
}
List<DataRow> _buildDataRows() {
return cf.coas.map<DataRow>((coa) {
final years = coa.values.keys.toList()..sort();
return DataRow(cells: [
DataCell(Text(coa.name)),
...years.map<DataCell>((year) {
final value = coa.values[year];
//TODO format value
return DataCell(Text(value.toString()));
})
]);
}).toList(growable: false);
}
}
Upvotes: 0
Views: 1018
Reputation: 54367
You can copy paste run full code below
Step 1: Consume original json string to related Map , in this demo class
Payload
Step 2: Transfer this Payload
to List
of year data
Step 3: use json_table
to consume List
of year data
working demo
code snippet
class Payload {
Map<String, double> acquisition;
Map<String, double> bpUplift;
Map<String, double> capex;
...
class YearData {
String year;
double acquisition;
double bpUplift;
double capex;
...
void transfer() {
Payload payload = payloadFromJson(jsonString);
List<YearData> yearDataList = [];
for (var val in payload.acquisition.keys) {
var year = val;
var acquisition = payload.acquisition[val];
var capex = payload.capex[val];
var bpUplift = payload.bpUplift[val];
yearDataList.add(YearData(
year: year,
acquisition: acquisition,
bpUplift: bpUplift,
capex: capex));
}
jsonSample = yearDataToJson(yearDataList);
}
full code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:json_table/json_table.dart';
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
Map<String, double> acquisition;
Map<String, double> bpUplift;
Map<String, double> capex;
Payload({
this.acquisition,
this.bpUplift,
this.capex,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
acquisition: Map.from(json["Acquisition"])
.map((k, v) => MapEntry<String, double>(k, v.toDouble())),
bpUplift: Map.from(json["BP Uplift"])
.map((k, v) => MapEntry<String, double>(k, v.toDouble())),
capex: Map.from(json["Capex"])
.map((k, v) => MapEntry<String, double>(k, v.toDouble())),
);
Map<String, dynamic> toJson() => {
"Acquisition": Map.from(acquisition)
.map((k, v) => MapEntry<String, dynamic>(k, v)),
"BP Uplift":
Map.from(bpUplift).map((k, v) => MapEntry<String, dynamic>(k, v)),
"Capex": Map.from(capex).map((k, v) => MapEntry<String, dynamic>(k, v)),
};
}
List<YearData> yearDataFromJson(String str) =>
List<YearData>.from(json.decode(str).map((x) => YearData.fromJson(x)));
String yearDataToJson(List<YearData> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class YearData {
String year;
double acquisition;
double bpUplift;
double capex;
YearData({
this.year,
this.acquisition,
this.bpUplift,
this.capex,
});
factory YearData.fromJson(Map<String, dynamic> json) => YearData(
year: json["year"],
acquisition: json["Acquisition"],
bpUplift: json["BPUplift"],
capex: json["Capex"],
);
Map<String, dynamic> toJson() => {
"year": year,
"Acquisition": acquisition,
"BPUplift": bpUplift,
"Capex": capex,
};
}
class SimpleTable extends StatefulWidget {
@override
_SimpleTableState createState() => _SimpleTableState();
}
class _SimpleTableState extends State<SimpleTable> {
String jsonString = '''
{
"Acquisition": {
"2019": -78600000,
"2020": 0,
"2021": 0,
"2022": 0,
"2023": 0,
"2024": 0,
"2025": 0,
"2026": 0,
"2027": 0,
"2028": 0,
"2029": 0,
"2030": 77527013.89465855
},
"BP Uplift": {
"2019": 0,
"2020": 0,
"2021": 0,
"2022": 0,
"2023": 0,
"2024": 0,
"2025": 0,
"2026": 0,
"2027": 0,
"2028": 0,
"2029": 0,
"2030": 0
},
"Capex": {
"2019": 0,
"2020": 0,
"2021": 0,
"2022": 0,
"2023": 0,
"2024": 0,
"2025": 0,
"2026": 0,
"2027": 0,
"2028": 0,
"2029": 0,
"2030": 0
}
}
''';
String jsonSample = "";
bool toggle = true;
List<YearData> yearDataList = [];
@override
void initState() {
// TODO: implement initState
transfer();
super.initState();
}
void transfer() {
Payload payload = payloadFromJson(jsonString);
List<YearData> yearDataList = [];
for (var val in payload.acquisition.keys) {
var year = val;
var acquisition = payload.acquisition[val];
var capex = payload.capex[val];
var bpUplift = payload.bpUplift[val];
yearDataList.add(YearData(
year: year,
acquisition: acquisition,
bpUplift: bpUplift,
capex: capex));
}
jsonSample = yearDataToJson(yearDataList);
}
@override
Widget build(BuildContext context) {
var json = jsonDecode(jsonSample);
return Scaffold(
body: Container(
padding: EdgeInsets.all(16.0),
child: toggle
? Column(
children: [
JsonTable(
json,
showColumnToggle: true,
tableHeaderBuilder: (String header) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: 8.0, vertical: 4.0),
decoration: BoxDecoration(
border: Border.all(width: 0.5),
color: Colors.grey[300]),
child: Text(
header,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.display1.copyWith(
fontWeight: FontWeight.w700,
fontSize: 14.0,
color: Colors.black87),
),
);
},
tableCellBuilder: (value) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: 4.0, vertical: 2.0),
decoration: BoxDecoration(
border: Border.all(
width: 0.5,
color: Colors.grey.withOpacity(0.5))),
child: Text(
value,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.display1.copyWith(
fontSize: 14.0, color: Colors.grey[900]),
),
);
},
allowRowHighlight: true,
rowHighlightColor: Colors.yellow[500].withOpacity(0.7),
paginationRowCount: 20,
),
SizedBox(
height: 20.0,
),
Text("Simple table which creates table direclty from json")
],
)
: Center(
child: Text(getPrettyJSONString(jsonSample)),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.grid_on),
onPressed: () {
setState(
() {
toggle = !toggle;
},
);
}),
);
}
String getPrettyJSONString(jsonObject) {
JsonEncoder encoder = new JsonEncoder.withIndent(' ');
String jsonString = encoder.convert(json.decode(jsonObject));
return jsonString;
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SimpleTable(),
);
}
}
Upvotes: 1