4

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.

2 Answers 2

1

You need to hold the state of all sliders. I'd recommend you the BLoC pattern for state management.

You can read about it here

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

Sign up to request clarification or add additional context in comments.

3 Comments

OK, I read it but would I need a Stream for each question (Slider)? do you have any code or could you point me to some example similar to solve my problem?
It took a while to learn and implement, but after doing it, I got an error saying something like "Stream is already listened to", I suppose it's because I can only attach one Slider to the Stream (???)
That's because you need to declare the StreamController like this StreamController.broadcast(). When you do this, the stream can be listened in multiple places. Without it you can only listen to it once
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.