0

I am updating the dropdown table dynamically from an API. When I select an hour, the corresponding subjects are retrieved from the API.

Let's say I am switching between hours.

Hour 5 has the subjects A and B while hour 4 has the subject B alone.

Hour 5 is initially selected with A as the selected subject.

When I select hour 4, the new list is obtained from the API but I get the "item not in dropdownbuttonitemlist error".

I understand that this is because of the value attribute of the DropDownMenuField, that's why I set the value to null on successful retrieval of info from the API.

hour 5 items image

hour 5 selected image

error after selecting hour 4

The snippets are below:

DropdownButton:

DropdownButtonFormField<String>(
                    isExpanded: true,
                    style: new TextStyle(
                      fontFamily: "Poppins",
                      fontWeight: FontWeight.w400,
                      color: Colors.black,
                    ),
                    decoration: InputDecoration(
                      contentPadding: const EdgeInsets.all(0),
                      labelText: "Select subject",
                      labelStyle: TextStyle(
                        fontFamily: "Poppins",
                        fontWeight: FontWeight.w200,
                        color: Colors.black,
                      ),
                    ),
                    value: subjectController,
                    onChanged: (value) {
                      setState(() {
                        pk_table =
                        pk_table_array[subject_array.indexOf(value)];
                        required_timestamp = required_timestamp_array[
                        subject_array.indexOf(value)];
                        subjectController = value;
                        buttonActive = true;
                      });
                    },
                    items: _subjectDropDownItems,
                  ),

setState method (invoked on API successful fetch):

setState(() {
  subjectController = null;
  buttonActive = true;
  subject_array.forEach((subject) {
    if (subjectController == null) {
      print("updated value");
      subjectController = subject;
    }
    _subjectDropDownItems.add(new DropdownMenuItem(
      child: new Text(subject.toString()),
      value: subject.toString(),
    ));
  });
});

subjectController is defined as an attribute of the State class.

And this is the error:

    There should be exactly one item with [DropdownButton]'s value: IT8551B - Web Technology Laboratory B. 
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value

Thank you for your help in advance!

2 Answers2

0

Let me to understand better your problem. Are you cleaning the list _subjectDropDownItems, because it seems like your adding just new element from the four option include duplicated values.

So, you can use a Set<String> = {} structure insteadm to prevent those duplications, because the DropdownButton doesn't allowed.

If you still need to show duplicated values, you can create a class as value for the DropdownMenuItem, like this DropdownMenuItem<YourClass>, add a id and override the == operator or try the Equatable library from Pub.dev for the same purpose.

Gauris Javier
  • 387
  • 4
  • 11
  • I am cleaning list before adding new elements. The problem is the value attribute of the DropDownButtonFormField is not updating to the new value on setState. The list is clean, I checked the values of the list too. The value of the DropDownButtonFormField is still from the old list even after setState. The new list doesn't contain any item with the same value. – Rahul Pon May 24 '20 at 08:08
  • Well, the error is not very descriptive, but checking the assert constructor for the **DropdownButtonFormField** widget you can notice that it's required a non-empty or null items, value should not be not null or empty. So, check if your using a either an empty string/null value or Items list lis, if so show Text widget when the list is empty instead or null. It seeams like Flutter don't like you use the **DropdownButtonFormField** widget when your list of element is empty or null. – Gauris Javier May 24 '20 at 16:52
  • Yeah it took me 3 days to fix this. Use DropdownButton in the place of DropdownButtonFormField if you need dynamic dropdowns. I've put the answer below. – Rahul Pon May 24 '20 at 18:10
0

The problem is with DropdownButtonFormField.

DropdownButtonFormField doesn't allow updating the value to the new one on with setState.

Use DropdownButton instead or assign a form key to DropdownButtonFormField and clear the form in setState when you need a dynamic/multi-level dropdown that needs to be updated on the fly.

This is what I did to fix.