Displaying complex json in FormBuilderRadioGroup in flutter_form_builder flutter

634 views Asked by At

I'm having trouble displaying 'option' and getting (print in terminal) the 'id' of the chosen option.

How can I retrieve the json as map and use it effectively in flutter_form_builder?

Here is the json object:

{
 id: 7,
 poll: What is the capital of Egypt?,
 created_at: 2020-10-22 10:53:41,
 votes_count: 4,
 likes_count: 0,
 options: [
{
  id: 20,
  option: Tunis,
  pollId: 7,
  votes_count: 1
}, {
  id: 21,
  option: Cairo,
  pollId: 7,
  votes_count: 3
}, {
  id: 22,
  option: New York,
  pollId: 7,
  votes_count: 0
}],
 user_name: salem,
 user_image: null,
 topics: []
}

Here is my poll_details page:

import 'package:flutter/material.dart';
import 'package:circular_profile_avatar/circular_profile_avatar.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:like_button/like_button.dart';

import '../services/poll_services.dart';

import '../widgets/loading_widget.dart';


class PollDetails extends StatefulWidget {

  final id;
  PollDetails({this.id});

  @override
  _PollDetailsState createState() => _PollDetailsState(id);
}

class _PollDetailsState extends State<PollDetails> {

  var id;
  _PollDetailsState(this.id);

  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

  @override
  void initState() {
    super.initState();
    optionsList.clear();
  }

  @override
  Widget build(BuildContext context) {

    return SafeArea(
      child: Scaffold(
        appBar: AppBar(title: Text("Details")),
        body: FutureBuilder(
          future: singlePoll(id),
          builder: (context, snapshot) {
            if(snapshot.hasData){
              return ListView(
                padding: EdgeInsets.fromLTRB(18, 40, 18, 0),
                children: [
                  Padding(
                    padding: EdgeInsets.only(bottom: 20),
                    child: Container(
                      padding: EdgeInsets.fromLTRB(10, 40, 0, 40),
                      decoration: BoxDecoration(
                        shape: BoxShape.rectangle,
                        borderRadius: BorderRadius.circular(10.0),
                        border: Border.all(
                          color: Theme.of(context).primaryColor,
                          width: 5.0,
                          style: BorderStyle.solid
                        )
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: [
                          if(imgPath(snapshot.data) == null) CircleAvatar(radius: 35,child: Image.asset('images/avatar.png'))
                          else CircularProfileAvatar(
                            imgPath(snapshot.data),
                            radius: 35,
                            borderWidth: 3.0,
                            borderColor: Colors.white,
                            backgroundColor: Colors.transparent,
                            foregroundColor: Colors.transparent,
                            errorWidget: (context, url, error) => Container(child: Icon(Icons.error)),
                            placeHolder: (context, url) => Container(
                              width: 50,
                              height: 50,
                              child: Text("Loading image..."),
                            )
                          ),
                          SizedBox(width: 10.0),
                          Expanded(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Text(
                                  userName(snapshot.data),
                                  style: TextStyle(fontSize: 20)
                                ),
                                Flexible(
                                  fit: FlexFit.loose,
                                  child: Text(
                                    votesCount(snapshot.data).toString()+" participants to this poll",
                                    style: TextStyle(fontSize: 13)
                                  )
                                )
                              ]
                            )
                          )
                        ]
                      )
                    )
                  ),
                  ///////////////////////////////// POLLS //////////////////////////////////////////////
                  FormBuilder(
                    key: _fbKey,
                    autovalidateMode: AutovalidateMode.always,
                    child: FormBuilderRadioGroup(
                      attribute: 'options',
                      decoration: InputDecoration(labelText: 'Choose only one:'),
                      validators: [FormBuilderValidators.required()],
                      orientation: GroupedRadioOrientation.vertical,
                      options: [
                        for (var i in optionsList) i['option'].toString()
                      ]
                        .map((option) => FormBuilderFieldOption(value: option))
                        .toList(growable: false),
                    )
                  ),
                  RaisedButton(
                    child: Text("Submit"),
                    onPressed: () async{
                      _fbKey.currentState.save();
                      if (_fbKey.currentState.validate()) {
                        // Loading().show(context);
                        var option = _fbKey.currentState.value['options'];
                        print(option);
                        // var resp = await createPoll(question, tagS, choiceS);
                        // if(resp['status'] == "success"){
                        //   Navigator.pop(context); //pop dialog
                        // } else {
                        //   Navigator.pop(context); //pop dialog
                        // }
                      }
                    }
                  ),
                  //////////////////////////// Like Button ///////////////////////////////
                  Row(
                    children: [
                      LikeButton(
                        size: 40,
                        circleColor:
                          CircleColor(start: Colors.red, end: Colors.red),
                        bubblesColor: BubblesColor(
                          dotPrimaryColor: Colors.red,
                          dotSecondaryColor: Colors.red,
                        ),
                        likeBuilder: (bool isLiked) {
                          return Icon(
                            Icons.favorite,
                            color: isLiked ? Colors.red : Colors.grey,
                            size: 40,
                          );
                        },
                        likeCount: likes(snapshot.data),
                        countBuilder: (int count, bool isLiked, String text) {
                          var color = isLiked ? Colors.red : Colors.grey;
                          Widget result;
                          if (count == 0) {
                            result = Text(
                              "0",
                              style: TextStyle(color: color),
                            );
                          } else
                            result = Text(
                              text,
                              style: TextStyle(color: color),
                            );
                          return result;
                        }
                      ),
                      Expanded(child: Text(" have liked this. Show some love, too!"))
                    ]
                  ),
                  Column(
                    children: [
                      // optionsList.forEach((element) => Text('option'))
                      for (var i in optionsList) Text(i['option'].toString())
                    ]
                  ),
                  RaisedButton(
                    child: Text("data"),
                    onPressed: (){singlePoll(id);}
                  )
                ]
              );
            }else {
              return Center(child: CircularProgressIndicator());
            }
          }
        )
      )
    );
  }
}

And here is the request I use to get the response:

Future singlePoll(int id) async {

  String url = baseUrl+"poll/get";
  var stringID = id.toString();
  var token = await storage.read(key: "jwt");

  try{
    final response = await http.post(
      url,
      headers: {'Accept':'application/json', 'Authorization':token},
      body: {'pollId':stringID}
    );
    var dataToJson = jsonDecode(response.body);

    for (var option in dataToJson['options']){
      var optionID = option['id'];
      var optionTitle = option['option'].toString();
      var votesCount = option['votes_count'];
      optionsList.add(option);
    }
    print(dataToJson);
    return dataToJson;
  } catch (e){
    print('error caught: $e');
  }
}

As you can see, I used a work around to get the list and display it.

Any suggestion is valuable.

Thanks in advance...

1

There are 1 answers

1
Akif On

You need to use setState() in here:

 setState() {
    var optionID = option['id'];
    var optionTitle = option['option'].toString();
    var votesCount = option['votes_count'];
    optionsList.add(option);
   }

You can read more from the official document and look at here.