My first suggestion will be to transform these data by using numbers instead of strings, so no matter if the label (ones
, twos
, etc...) changes in the future, it won't affect your code:
void main() {
final data = {
"success": true,
"data": {
"ones": [
{ "id": "2", "username": "LM10002" },
{ "id": "6", "username": "LM10006" }
],
"twos": [
{ "id": "3", "username": "LM10003" },
{ "id": "8", "username": "LM10008" }
]
}
};
print(ApiResponse.fromJson(data));
}
class ApiResponse {
final bool success;
final List<List<Data>> data;
ApiResponse({this.success, this.data});
factory ApiResponse.fromJson(Map<String, dynamic> json) {
List<List<Data>> dataList = [];
final jsonData = (json["data"] as Map<String, dynamic>);
jsonData.values.forEach((value) {
List<Data> parsedList = List<Data>.from(List.from(value).map((element) => Data.fromJson(element)));
dataList.add(parsedList);
});
return ApiResponse(
success: json["success"],
data: dataList,
);
}
@override
String toString() {
return "Success: $success, Data: ${data.map((element) => element.map((d) => "${d.id} ${d.username}")).toList().join("; ")}";
}
}
class Data {
final String id;
final String username;
Data({this.id, this.username});
factory Data.fromJson(Map<String, dynamic> json) {
return Data(
id: json["id"],
username: json["username"],
);
}
}
This should return a list of data where each index+1
will represent the order (ones, or twos, etc...), and the value attached will directly be the list of data.
The print statement in the main function will print this : Success: true, Data: (2 LM10002, 6 LM10006); (3 LM10003, 8 LM10008)
.
The second approach would be to add a group
attribute to each of your data so that for each of them, you know to which group it belongs (ones, twos, etc...)
Here is the full implementation:
void main() {
final data = {
"success": true,
"data": {
"ones": [
{ "id": "2", "username": "LM10002" },
{ "id": "6", "username": "LM10006" }
],
"twos": [
{ "id": "3", "username": "LM10003" },
{ "id": "8", "username": "LM10008" }
]
}
};
print(ApiResponse.fromJson(data));
}
class ApiResponse {
final bool success;
final List<Data> data;
ApiResponse({this.success, this.data});
factory ApiResponse.fromJson(Map<String, dynamic> json) {
List<Data> dataList = [];
final jsonData = (json["data"] as Map<String, dynamic>);
jsonData.forEach((key, value) {
List<Data> parsedList = List<Data>.from(List.from(value).map((element) {
element["group"] = key;
return Data.fromJson(element);
}));
dataList.addAll(parsedList);
});
return ApiResponse(
success: json["success"],
data: dataList,
);
}
@override
String toString() {
return "Success: $success, Data: ${data.map((element) => "${element.id}, ${element.username}, ${element.group}")}";
}
}
class Data {
final String id;
final String username;
final String group;
Data({this.id, this.username, this.group});
factory Data.fromJson(Map<String, dynamic> json) {
return Data(
id: json["id"],
username: json["username"],
group: json["group"]
);
}
}
The print statement in the main method should print : Success: true, Data: (2, LM10002, ones, 6, LM10006, ones, 3, LM10003, twos, 8, LM10008, twos)
To recapitulate:
Solution |
Description |
Advantage |
Disadvantage |
#1 |
Proposes to represent the data in the form of a matrix with in ordinates the indexes-1 of the "groups" of data, and in abcissa, the data themselves |
We keep the order of the data and it is easy to sort them |
Not great for readability, and the group labels returned by the API are |
#2 |
Allows to keep the labels as strings and add them to the data (to later filter the data automatically according to the groups) |
We keep the initial data group labels |
It will be more difficult to perform sorting |