I am developing a Web Survey Form in Flutter that uses a self hosted Supabase for the database. I am now storing the answers and retrieving it for initialization and for further analysis. This question emerged after I solved my previous post. I am having difficulty in storing in a data model a field which is a jsonb data type, which consist of a list of <String, int>. Here is the schema used to create the table responses
CREATE TABLE responses (
id SERIAL PRIMARY KEY,
respondent_id UUID REFERENCES respondents(id) NOT NULL,
assessment_cycle_id INT REFERENCES assessment_cycle(id) NOT NULL,
response_date DATE,
answers JSONB,
finished BOOLEAN
);
A sample entry in the answers field is this:
{"1":1,"2":1,"3":3,"4":1,"5":0,"6":3,"7":3,"8":3,"9":2,"10":2,"11":1,"12":3,"13":3,"15":1,"14":3,"16":3,"17":3,"18":3,"19":2,"20":1}
Here is the current data model:
class Response {
final int? id;
final String respondentId;
final int assessmentCycleId;
final DateTime responseDate;
final Map<String, dynamic> answers;
final bool? finished;
Response({
this.id,
required this.respondentId,
required this.assessmentCycleId,
required this.responseDate,
required this.answers,
this.finished,
});
factory Response.fromJson(Map<String, dynamic> json) {
return Response(
id: json['id'],
respondentId: json['respondent_id'],
assessmentCycleId: json['assessment_cycle_id'],
responseDate: DateTime.parse(json['response_date']),
answers: json['answers'] is Map<String, dynamic>
? Map<String, dynamic>.from(json['answers'])
: {},
finished: json['finished'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'respondent_id': respondentId,
'assessment_cycle_id': assessmentCycleId,
'response_date': responseDate.toIso8601String(),
'answers': answers,
'finished': finished,
};
}
}
Here is the repository.
class ResponseRepository {
final supabase = Supabase.instance.client;
Future<Response?> getResponse(
String respondentId, int assessmentCycleId) async {
try {
final response = await supabase
.from('responses')
.select()
.eq('respondent_id', respondentId)
.eq('assessment_cycle_id', assessmentCycleId)
.single();
if (response.isNotEmpty) {
print('Response: $response');
return Response.fromJson(response);
} else {
return null;
}
} catch (error) {
throw Exception('Error fetching questions: $error');
}
}
}
I tried to print the value of response to check, and it retrieved the results correctly including answers. However, in the Survey Page where the questions and answers will be printed, when I tried to initialize the value of answers, it was empty.
class _SurveyPageState extends ConsumerState<SurveyPage> {
...
final Map<String, dynamic> _answers = {};
Future<void> _fetchInitialAnswer(String respondentId) async {
try {
Response? initialAnswer = await _responseRepository.getResponse(
respondentId, assessmentCycleId);
if (initialAnswer != null) {
print('Initial Answer ${initialAnswer.toJson()}');
_answers.clear();
_answers.addAll(initialAnswer.answers);
print('Answers: $_answers');
}
} catch (error) {
const SnackBar(
content: Text('Unexpected Error in fetching saved answers'),
);
}
}
...
Here, I tried to print the initialAnswer in the line print('Initial Answer ${initialAnswer.toJson()}'); which is of a Response type that was retrieved from the getResponse. It printed all values except the answers which is just {}. So it means the field in the data model is incorrect.
answers: json['answers'] is Map<String, dynamic>
? Map<String, dynamic>.from(json['answers'])
: {},
How will I rectify this, and later assigned the values so it can be initialized correctly? I am really new to Flutter and Supabase and relying in Microsoft Bing/Copilot but it keeps showing deprecated solutions so I am stuck. Thanks in advance!