Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart / flutter: DropdownButton causes exception when value is changed

Tags:

flutter

dart

I have written a pretty extensive form using DropdownButton and TextField widgets. The concept is that I have a StatefulWidget, where the class of State<StatefulWidget> contains 2 methods that return the widget I want to build. This way I can easily access and use the entered data and pass it along a function to compose an e-mail out of them.

However, when I select an item from the options, the framework throws an exception during the rebuild. I put in some log functions, and it shows that the setState() method successfully saves the value to selectedValue variable.

Widget buildMultiChoiceInputRow(var label, List<String> values) {
    final List<String> options = values.toList();
    selection = options.first;

    final dropDownMenuOptions = options.map((String value) {
      return new DropdownMenuItem<String>(
        value: value,
        child: new Text(value),
      );
    }).toList();

    return new Column(
      children: <Widget>[
        new Row(
          children: <Widget>[
            new Expanded(
              child: new Container(
                  padding:
                      const EdgeInsets.only(left: 5.0, top: 2.0, right: 5.0),
                  child: new Text(label, style: commonInfoCardInfoTextBlack16Bold)),
            ),
          ],
        ),
        new Row(
          children: <Widget>[
            new Expanded(
              child: new Container(
                padding: const EdgeInsets.only(left: 5.0, right: 5.0),
                child: new DropdownButton(
                value: selectedValue,
                items: dropDownMenuOptions,
                onChanged: (selection) {
                  setState(() {
                    selectedValue = selection;
                    switch (label) {
                      case labelVirtualAdoption:
                        tempAdoptionType =
                            composeMultiChoiceAnswer(label, selection);
                            print(selection);
                            print(selectedValue);
                        break;
                          case labelAskedAboutSpecies:
                            tempAskedAboutSpecies =
                                composeMultiChoiceAnswer(label, selection);
                            break;
                          case labelHouseOrFlat:
                            tempHouseOrFlat =
                                composeMultiChoiceAnswer(label, selection);
                            break;
                            ....
                          default:
                            break;
                        }
                      });
                    }),
              ),
            )
          ],
        ),
        new Divider(color: Colors.transparent)
      ],
    );
  }

Here is the exception:

I/flutter (20998): The following assertion was thrown building AdoptionInput(dirty, state: AdoptionInputState#3cc80):
I/flutter (20998): 'package:flutter/src/material/dropdown.dart': Failed assertion: line 481 pos 15: 'value == null ||
I/flutter (20998): items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not true.

And here is the stack, showing that the exception is thrown during the rebuild:

I/flutter (20998): #2      new DropdownButton (package:flutter/src/material/dropdown.dart)
I/flutter (20998): #3      AdoptionInputState.buildMultiChoiceInputRow (package:osszefogasaszanhuzokert/adoptionPageUtilities.dart:443:28)
I/flutter (20998): #4      AdoptionInputState.build (package:osszefogasaszanhuzokert/adoptionPageUtilities.dart:639:11)
I/flutter (20998): #5      StatefulElement.build (package:flutter/src/widgets/framework.dart:3730:27)
I/flutter (20998): #6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3642:15)
I/flutter (20998): #7      Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (20998): #8      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2242:33)

The problem seems really similar to a former bug in flutter, but if I try to initialize the selection and selectedValue in initState(), the same exception will be thrown right as the form is built for the first time.

What am I missing here?

like image 882
Zoltán Györkei Avatar asked May 17 '18 06:05

Zoltán Györkei


2 Answers

Your "value" for DropdownButton should be set to 'null' or or be one from the values list.

DropdownButton(
      value: null,
      isDense: true,
      onChanged: (String newValue) {
        // somehow set here selected 'value' above whith 
       // newValue
       // via setState or reactive.
      },
      items: ['yellow', 'brown', 'silver'].map((String value) {
        return DropdownMenuItem(
          value: value,
          child: Text(value),
        );
      }).toList(),
    ),

So for my example DropdownButton value should be set to null or be 'yellow' or 'brown' or 'silver'.

like image 60
Evgeniy Volk Avatar answered Nov 19 '22 05:11

Evgeniy Volk


Extending above answer with the second case where I was stuck.

Your "value" for DropdownButton should be set to 'null' or be one from the values list.

Your 'values' should also be different in every item value.

for example: Avoid this

 items.add(DropdownMenuItem(
  value: 1.toString(),
  child: Text(1.toString()),
));
items.add(DropdownMenuItem(
  value: 1.toString(),
  child: Text(1.toString()),
));

Avoid repeating the values.

like image 13
vivek yadav Avatar answered Nov 19 '22 06:11

vivek yadav