Reputation: 457
I've managed to make a dynamic questionnaire connecting flutter with Firestore.
My custom Question widgets are just a Text() holding the string of the question, and a Slider() so the user can give an answer from 1 to 5
Now that the questions are displayed, how should I get the values?
Here's my code:
var questions = <Widget>[];
//Async read to the DB
Future query() async {
var snap = await Firestore.instance
.collection("Forms")
.document(formID)
.get();
var arr = <Widget>[]; //just a temp holder of the widgets
for(String q in list){
arr.add(Question(min: 1.0, max: 5.0, question: q, value: 1.0,));
}
setState(() {
questions = arr;
});
}
And then in the build I'm rendering:
Scaffold(
body:Container(
child:Column(
children: <Widget>[
Text("Title"),
Column(
children: questions,
),
RaisedButton(
onPressed: () => sendFeedback(),
color: Colors.redAccent,
textColor: Colors.white,
child: Text("Send")
]
)
What would be the code for the sendFeedback() function? I would like to get the values for all the sliders in my children list and then write those to Firestore in only one call to the DB.
Upvotes: 4
Views: 2396
Reputation: 457
For the purpose of this app, it's enough to have a global variable
Map<String, double> responses = Map();
that is reset when I navigate into a questionnaire, and then each Slider has to update the Map like so (onChange):
Slider(
value: value,
min: widget.min,
max: widget.max,
divisions: (widget.max - 1).round(),
label: value.ceil().toString(),
activeColor: color,
onChanged: (double val1) {
//Force a re-render
setState(() {
//Update the value of the Slider
value = val1;
//Do some operations, assign a color based on the result
double p = value / widget.max;
if (p > 0 && p <= 0.3) {
color = Colors.red;
} else if (p > 0.3 && p <= 0.6) {
color = Colors.orangeAccent;
} else {
color = Colors.green;
}
//Update the value of the parent Widget
widget.value = value;
ratings[widget.question] = value;
//Done, print in console for debugging
print(value);
});
})
I invested quite some time into the BLoC pattern, but I couldn't make it work as expected. Maybe I'll try it again soon and post back the solution.
Upvotes: 0
Reputation: 3894
You need to hold the state of all sliders. I'd recommend you the BLoC pattern for state management.
Edit: You can have a List<int>
to hold the values in your bloc and in every slider you will implement the function onChangeEnd: bloc.addValue
and send the slider value to the bloc which will add them to the list.
Then on the button you will have something like this onPressed: () => bloc.sendFeedback()
that will take the values from the list and write them to Firestore.
Keep in mind that this is a solution on the top of my head right now for you to understand the concept
Upvotes: 1