I am querying an API endpoint (on my Node API, which I can modify) and I expect the result to be of a certain complex type. I see no real way to share types between Node and a Flutter frontend, so I define types myself like so:
enum QuestionType {
text,
recording,
goal,
}
class Question {
final String question;
final String? subtitle;
// final QuestionType type;
final int? timeInSeconds;
final int? askGoalAfterDays;
final bool userSubmitted;
Question(
{required this.question,
// required this.type,
this.subtitle,
this.timeInSeconds,
this.askGoalAfterDays,
this.userSubmitted = false});
}
I hit an endpoint and get a list of these types. The response body is:
[{
"id": 93,
"createdAt": "2023-03-04T02:35:24.514Z",
"updatedAt": "2023-03-04T02:36:36.000Z",
"question": "...",
"subtitle": null,
"type": "Gratitude",
"timeInSeconds": 20,
"askGoalAfterDays": null,
"userSubmitted": false
}, {
"id": 3,
"createdAt": "2023-03-04T02:35:24.546Z",
"updatedAt": "2023-03-04T02:35:24.546Z",
"question": "...",
"subtitle": null,
"type": "Rating",
"timeInSeconds": null,
"askGoalAfterDays": null,
"userSubmitted": false
}, {
"id": 2,
"createdAt": "2023-03-04T02:35:24.548Z",
"updatedAt": "2023-03-04T02:36:36.000Z",
"question": "...",
"subtitle": null,
"type": "Goal",
"timeInSeconds": 20,
"askGoalAfterDays": 0,
"userSubmitted": false
}]
I call the API and attempt to parse the content like so:
static Future<List<QuestionType>> getDaytime() async {
// ...
var response = await http.get(url);
var res = jsonDecode(response.body) as List<QuestionType>; <-- ERROR
if (response.statusCode == 200) {
return [res[0], res[1]];
} else {
throw AdException(response.statusCode.toString());
}
}
However when I try to parse the response I get the following error:
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<QuestionType>' in type cast
A few questions:
Why am I getting this error?
Is this the best way to parse and type content received from an API? There is obviously code duplication between my frontend and backend types, which seems wasteful.
2
Answers
You can do this:
Create a factory constructor to convert from json to class instance:
And then you can parse your response body to json and then
map
toList
:I dont know if this can help you but I’ll give it a try:
You should try to place a
fromJson(Map<String,dynamic>)
method in your Question class.So basically your class will look something like this:
Now instead of doing
var res = jsonEncode(response.body);
, you should cycle the element inside response body and put it inside a new array and return it as response like this:Hope it helps! 😀