0
votes

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

2 Answers

0
votes

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.

0
votes

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.