0

I am getting response where getting getting different property of shape initially.

{
    "success": true,
    "data": {
         "pcode": "001",
         "pname": "ABC",
         "pprice": "100"
        "ones": [{
                "id": "2",
                "username": "LM10002"
            },
            {
                "id": "6",
                "username": "LM10006"
            }
        ],
        "twos": [{
                "id": "3",
                "username": "LM10003"
            },
            {
                "id": "8",
                "username": "LM10008"
            }
        ],
        ]
    }
}

here "ones","twos" ..that are dynamic key in future add new array also. so we can manage that dynamically in flutter ?

Sachin Suthar
  • 692
  • 10
  • 28

2 Answers2

1

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
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Steve
  • 914
  • 8
  • 17
  • this is fine but how access this field. "pcode": "001", "pname": "ABC", "pprice": "100" These are fix. – Sachin Suthar Mar 23 '21 at 13:31
  • It's going to be tricky. I would have advised you to better format the data on the backend before sending it back to the frontend. It would be easier and cleaner to send the same data format to the frontend for each call. – Steve Mar 23 '21 at 14:04
0

You can create a class to handle this kind of response. You will be able to access the different keys of the map assigned to the data key and perform any action you want on it.

class CustomResponse {
  bool success;
  Map<String, dynamic> data;
  
  CustomResponse(this.success, this.data);
  
  factory CustomResponse.fromJson(Map json) {
    return CustomResponse(
      json['success'] as bool,
      json['data'] as Map<String, dynamic>,
    );    
  }
}

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" } 
      ] 
    }
  };
  
  final customResponse =  CustomResponse.fromJson(data);
  print(customResponse.data.keys);  
}
glavigno
  • 483
  • 5
  • 10
  • And what if the response can vary ? From what i've understood, he could have either a response with twos, or a response without, or with twos, threes, etc.... I don't think your solution will be sufficient in those cases – Steve Mar 23 '21 at 12:33