I have a flutter application retrieving a list/or anything for that matter at some point, and if there's any issue with the request, a different response is received.
For Example:
{
"status" : "success",
"message":
[
{
"updated_on" : "2022-01-09 14:26:07"
}
]
}
For Failure:
{
"status" : "error",
"message" : "Query not found"
}
Using quicktype.io, I have created class as below:
class ResponseList {
ResponseList({
required this.status,
required this.message,
});
String status;
List<dynamic> message;
factory ResponseList.fromJson(Map<String, dynamic> json) => ResponseList(
status: json["status"],
message: List<dynamic>.from(json["message"].map((x) => CLASSNAME.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": List<dynamic>.from(message.map((x) => x.toJson())),
};
}
Now, the problem is, on failure, this raises an exception when i try to call ResponseList responseAllFromJson(String str) => ResponseList.fromJson(json.decode(str));
where the exeption says
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'String' is not a subtype of type 'List<dynamic>'
.
I want to have a method that checks the status first, whether success or failure and then parses the remaining of the json (in message
) or parses the whole json and returns appropriate response (text in case of failure and list of objects in case of success).
Note: I want a reusable code, so that I can pass the response to the method and retrieve it from any point in my application. For example:
static bool responseStatus(dynamic response) {
if (response != null) {
if (responseListFromJson(response).status.trim().toLowerCase() == 'success') {
return true;
}
}
return false;
}
Presently, above raises exception on failure but works smoothly on success.
You can try this way while parsing.
class MainResponse {
String status;
dynamic message;
MainResponse({this.status, this.message});
MainResponse.fromJson(Map<String, dynamic> json) {
status = json['status'];
if(json['message'] is String) {
message = json['message'];
}else {
message = <Message>[];
json['message'].forEach((v) {
message.add(new Message.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
if (this.message != null) {
if(this.message is String) {
data['message'] = this.message;
}else {
data['message'] = this.message.map((v) => v.toJson()).toList();
}
}
return data;
}
}
class Message {
String updatedOn;
Message({this.updatedOn});
Message.fromJson(Map<String, dynamic> json) {
updatedOn = json['updated_on'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['updated_on'] = this.updatedOn;
return data;
}
}
And call this way :
MainResponse mainResponse = MainResponse.fromJson(response);
and this :
if(mainResponse.message is String) {
var data = mainResponse.message as String;
print('parsed String $data');
}else {
var list = mainResponse.message as List<Message>;
print('parsed ${list[0].updatedOn }');
}