I'm trying to convert a JSON object array to an Object of List<Map<String, dynamic>>
which a dynamic
part is a List<Object>
.
From this:
# RAW JSON
{
"apidata_": [
{"id":1,
"string_":"a",
"groupedString_":"G1"},
{"id":2,
"string_":"b",
"groupedString_":"G2"},
{"id":3,
"string_":"c",
"groupedString_":"G2"}
]
}
To this:
# Result grouped JSON
{
[
{
"groupedString_":"G1",
"apidata_":[
{"id":1,"string_":"a"}
]
},
{
"groupedString_":"G2",
"apidata_":[
{"id":2,"string_":"b"},
{"id":3,"string_":"c"}
]
}
]
}
This is a Class for the object from object of RAW JSON API
class ListOfAPIData {
ListOfAPIData({required this.apidata_});
List<APIData> apidata_;
factory ListOfAPIData.fromJson(Map<String, dynamic> json) => ListOfAPIData(
apidata_:
List<APIData>.from(json['apidata_'].map((e) => APIData.fromJson(e))));
Map<String, dynamic> toJson() =>
{"data": List<dynamic>.from(apidata_.map((e) => e.toJson()))};
}
class APIData {
APIData({
required this.id_,
required this.string_,
required this.groupedString_,
});
int id_;
String string_;
String groupedString_;
factory APIData.fromJson(Map<String, dynamic> json) => APIData(
id_: json["id_"],
string_: json["string_"],
groupedString_: json["groupedString_"]);
Map<String, dynamic> toJson() =>
{"id_": id_, "string_": string_, "groupedString_": groupedString_};
}
And this is a Class for the grouped object
class APIDataGrouped {
APIDataGrouped({required this.groupedString_, required this.apidata_});
String? groupedString_;
List<APIData>? apidata_;
factory APIDataGrouped.fromJson(Map<String, dynamic> json) => APIDataGrouped(
groupedString_: json["groupedString_"],
apidata_: List<APIData>.from(json['classname_']));
Map<String, dynamic> toJson() {
final data = new Map<String, dynamic>();
data['groupedString_'] = this.groupedString_;
data['classname_'] = this.apidata_!.map((e) => e.toJson()).toList();
return data;
}
}
I have manage to make a List<Map<String, dynamic>>
using groupBy()
, but after that I've tried many ways and facing many errors like: List<dynamic> is not a subtype of <Map<String, dynamic>>
, FormatException: unexpected character
, etc. I alway get error because APIDataGrouped only accept Map<String, dynamic>
as parameter but I cant provide it. Below is my Class for fetching data from the API.
class CallAPI {
Future<ListOfAPIData> fetchdata() async {
final respon = await get(Uri.http("serverAPI", '/path/of/API'));
final body = jsonDecode(respon.body);
final ListOfAPIData data;
if (respon.statusCode == 200 && body != null) {
data = ListOfAPIData.fromJson(body);
return data;
} else {
throw "error";
}
}
Future<APIDataGrouped> datagrouped() async {
var data = await fetchdata();
final g = groupBy(
data.apidata_,
(p0) => (p0 as APIData).groupedString_,
);
final d = <Map<String, dynamic>>[];
g.forEach((key, value) {
d.add({
"groupedString_": key,
"apidata_": value
.map((e) => Map.from(e.toJson())..remove('groupedString_'))
.toList()
});
});
final datafinal = d.reduce((value, element) {
value.addAll(element);
return value;
});
return APIDataGrouped.fromJson(datafinal);
}
}
CodePudding user response:
Lets assume your api json called jsonData
then you can use this approach:
var grouped = groupBy(jsonData["apidata_"] as List<Map<String, dynamic>>,
(Map value) => value['groupedString_']);
var result = grouped.entries.map((e) {
return {
"groupedString_": e.key,
"apidata_": e.value
.map((element) =>
{"id": element["id"], "string_": element["string_"]})
.toList()
};
}).toList();
print("result = $result"); // result = [{groupedString_: G1, apidata_: [{id: 1, string_: a}]}, {groupedString_: G2, apidata_: [{id: 2, string_: b}, {id: 3, string_: c}]}]