I have a flutter application, which uses some server APIs.
When there is a successful response from the server, it would return json back:
{"success": true, "message": "success", "data": {"id": "21EE"} }
However, when there is failure, it would return:
{"success": false, "message": "failure"}
For more strict-typed use of flutter, I try to model the response.
Here is my try:
class ServerResponse {
final bool success;
final String message;
ServerResponse({
required this.success,
required this.message,
});
}
class _AuthAutenticationData {
final String id;
_AuthAutenticationData({
required this.id,
});
}
class AutoAuthenticateResponse extends ServerResponse {
final _AuthAutenticationData? data;
AutoAuthenticateResponse({
required success,
required message,
this.data,
}) : super(success: success, message: message);
}
Now, I have a function which calls a specific API:
Future<void> autoAuth() async {
final url = Uri.parse('${this._baseURL.toString()}/auto-auth');
try {
final response = await http.post(url, headers: {
'Authorization': 'SXXX',
});
print(response.body);
final AutoAuthenticateResponse responseBody = json.decode(response.body);
if (responseBody.success) {
return setUser(new User(id: responseBody.data!.id));
}
setUser(null);
} catch (error) {
print(error);
setUser(null);
}
}
Some code is irrelevant, but bottom line is that I receive the following error in the line: final AutoAuthenticateResponse responseBody = json.decode(response.body);
:
I/flutter (14139): type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'AutoAuthenticateResponse'
I guess my solution is bad. Any advice how to fix it?
CodePudding user response:
Use this link to generate models for your response
CodePudding user response:
Well, you can use nullsafety
feature for this. Since it's only if when the failure the data
is not being returned.
{"success": true, "message": "success", "data": {"id": "21EE"} }
you can use this : https://meruya-techhnology.github.io/json-to-dart/
Then the result will be a 2 class
class YourClass {
final bool success;
final String message;
final Data? data;
YourClass({this.success, this.message, this.data});
factory YourClass.fromJson(Map<String, dynamic> json) => YourClass(
success : json['success'],
message : json['message'],
data : json['data'] != null ? new Data.fromJson(json['data']) : null;
);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['success'] = this.success;
data['message'] = this.message;
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
And
class Data {
String id;
Data({this.id});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
return data;
}
}
Then you can use it like this :
Future<void> autoAuth() async {
final url = Uri.parse('${this._baseURL.toString()}/auto-auth');
try {
final response = await http.post(url, headers: {
'Authorization': 'SXXX',
});
debugPrint(response.body);
final responseBody = YourClass.fromJson(response.body)
if (responseBody.success) {
return setUser(new User(id: responseBody.data!.id));
}
setUser(null);
} catch (error) {
print(error);
setUser(null);
}
}
another advice is use debugPrint
instead of print
, here you can read more : https://medium.com/flutter-community/debugprint-and-the-power-of-hiding-and-customizing-your-logs-in-dart-86881df05929