How to set Dropdownbutton's Items with data from Web in Flutter?

58 Views Asked by At

I'm making an app using Flutter.
What I want to do is DropboxList's Items attribute setting with data from web, which I obtain by Http.get.

However, because of synchronization problem (I guess), it's hard to control.

The following is my code and I leave annotations where the problem occur.
Is there anyone how has any idea about it?
Thank you.

==============================================

Get Data From Web by HTTP Get

 Future<List<DriveRecordForm>> getData() async {
    return await http.get(URL).then((response) {
      var jsonFeedback = convert.jsonDecode(response.body) as List;
      return jsonFeedback
          .map((json) => DriveRecordForm.fromJson(json))
          .toList();
    });
  }

Main Code

class _MyHomePageState extends State<MyHomePage> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  List<String> _valueList = ['null'];
  String _SelectedCar = 'null';
  List<DriveRecordForm> Records = List<DriveRecordForm>();

  @override
  void initState() {
    FormController().getData().then((value) {
      setState(() {
        this.Records = value;      // !!! Get Data from Web and assign to Records.
      });
    });
    
    /* ↓ !!! Problem Here
         Use Records. 
         But this line is executed before 'this.Records = value' is executed. 
         Thus Records is empty.*/

    SpreadSheetUtil().FilterData(Records, "CarList");   

    _valueList[0] = Records[0];       // Set _valueList to set DropdownList's items attribute
    _valueList[1] = Records[1];       // Set _valueList to set DropdownList's items attribute
    _valueList[2] = Records[2];       // Set _valueList to set DropdownList's items attribute
    
    _SelectedCar = _valueList[0];     // Set __SelectedCar to set DropdownList's value attribute
  } 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      resizeToAvoidBottomPadding: false,
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: ListView(
        children: <Widget>[
          Column(
            children: <Widget>[
              Row(
                children: <Widget>[
                  Expanded(
                    child: DropdownButton(
                      value: _SelectedCar,
                      items: _valueList.map((value) {     //  Assign _valueList but it's empty.
                        return DropdownMenuItem(
                          value: value,
                          child: Text(value),
                        );
                      }).toList(),
                      onChanged: (value) {
                        setState(() {
                          _SelectedCar = value;
                        });
                      },
                    ),
                  ),
1

There are 1 best solutions below

1
On BEST ANSWER

You need to fill your valueList after your getData() method. It will look like this:

@override
  void initState() {
    FormController().getData().then((value) {
      setState(() {
        this.Records = value;      // !!! Get Data from Web and assign to Records.

    SpreadSheetUtil().FilterData(Records, "CarList");   

    _valueList[0] = Records[0];       // Set _valueList to set DropdownList's items attribute
    _valueList[1] = Records[1];       // Set _valueList to set DropdownList's items attribute
    _valueList[2] = Records[2];       // Set _valueList to set DropdownList's items attribute
    
    _SelectedCar = _valueList[0];     // Set __SelectedCar to set DropdownList's value attribute

      });
    });
    
  
  }