tomerpacific
tomerpacific

Reputation: 6465

Updating Dropdown Data In Flutter Gives Error

I am in the process of developing a widget that consists of a dropdownbutton in Flutter. This widget creates dropdownmenuitems after making a request to a url the user has passed in.

I have seen the call being made and the response being valid, but when I use setState to update the data source for the dropdown I get the following error:

'package:flutter/src/material/dropdown.dart': Failed assertion: line 560 pos 15: 'items == null || I/flutter (11514): items.isEmpty || value == null || items.where((DropdownMenuItem item) => item.value == I/flutter (11514): value).length == 1': is not true.

I tried researching this error and found no helpful answers. The code is below:

class _MyWidgetState extends State<MyWidget> {

List<DropdownMenuItem<String>> _data = [];
String _selected = '';

@override
void initState() {
   super.initState();
   _loadData();
 }
 void _loadData() async {
    if (widget.urlToFetchData.isNotEmpty) {
      var response = await http.get(widget.urlToFetchData);
      if (response.statusCode == 200) {
         Map<String, dynamic> jsonResponse = convert.jsonDecode(response.body);
         jsonResponse.forEach((key, value){
           setState(() {
                  this._data.add(new DropdownMenuItem(
                                  child: new Text(value.toString()),
                                  value: value.toString(),
                             ));
           });
         });
      } else {
         print("Request failed with status: ${response.statusCode}.");
       }
    }
  }
}

@override
Widget build(BuildContext context) {
   if (_data.length == 0) {
      return new Container();
   } else {
        return Column(
            children: <Widget> [
                  new Text(
                    widget.dropdownLabelTitle
                 ),
                DropdownButton(
                     value: _selected,
                     items: _data,
                     hint: new Text(widget.defaultOptionText),
                     onChanged: (value) {
                        _selected = value;
                        widget.valueReturned(_selected);
                        setState(() {

                        });
                     }
                   )
                ],
              );
            }
       }
    }

Now, I am fully aware that at the initialization of the widget, the items field in the dropdownbutton is initialized with an empty list, but I thought that by calling setState when the http call finishes, it will update the value.

I have tried different methods of updating the data(by creating a local list and then using addAll or just by assignment), but I get the same error.

Anyone know how to solve this issue?

Upvotes: 3

Views: 10023

Answers (3)

Rasel Khan
Rasel Khan

Reputation: 4239

It's will be workable. You have to insert at least one data in array and in value.

List<DropdownMenuItem<String>> _data = ['Select One'];
String _selected = _data[0];

or you can do like this ---->

List<DropdownMenuItem<String>> _data = [];
String _selected = '';
_data.length > 0 ? DropdownButton(
                     value: _selected,
                     items: _data,
                     hint: new Text(widget.defaultOptionText),
                     onChanged: (value) {
                        _selected = value;
                        widget.valueReturned(_selected);
                        setState(() {

                        });
                     }
                   ) : Container();

Upvotes: 0

danypata
danypata

Reputation: 10175

Your problem is caused indeed by the _selected value. It has to be in the list of DropdownMenuItem so in your case the first value is an empty string and there are no items so that's ok, but when you get the values from the API there is no DropdownMenuItem that has the value=='' so the fix would be to init the _selected with the first value received from the API. Also you should setState outside the for loop. Something like this:

setState(() {
      jsonResponse.forEach((key, value) {
        if (_selected.isEmpty) {
          _selected = value;
        }
        this._data.add(new DropdownMenuItem(
              child: new Text(value.toString()),
              value: value.toString(),
            ));
      });
    });

Upvotes: 4

Adelina
Adelina

Reputation: 11881

You are getting this error because dropdown menu is trying to select item that does not exists.

DropdownButton(
        value: _selected, # < here you are trying to select `String _selected = '';`
        items: _data,

To solve this simple remove value or set it somewhere.

Upvotes: 7

Related Questions