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 |