DropdownButtonFormField reset value to initial

Question

Asked by Chiliaz on November 07, 2021 (source).

How do I reset or select the first value from DropdownButtonFormField? The answer from here How to reset value in Flutter DropdownButtonFormField is outdated and not suitable for the newer flutter version.

DropdownButtonFormField:

final etSkillScore1Key = GlobalKey<FormState>();
...
DropdownButtonFormField(
          key: etSkillScore1Key,
          decoration: const InputDecoration(labelText: 'Select value'),
          onChanged: (val) async {
            setState(() {
              etSkillScore1 = val as int;
            });

            FocusScope.of(context).requestFocus(FocusNode());
          },
          value: etSkillScore1,
          items: priorities2.map((db.Priority priorities) {
            return DropdownMenuItem(
              child: Text(priorities.name),
              value: priorities.value,
            );
          }).toList(),
        ),

Button for resetting the value:

IconButton(
              onPressed: () {
                //ERORR: Null check operator used on a null value
                etSkillScore1Key.currentState!.reset();
              },
              icon: Icon(
                Icons.close,
              ))

Error:

======== Exception caught by gesture
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value

If I use

etSkillScore1Key.currentState?.reset();

then nothing happens

Answer

Question answered by Guillaume R (source).

First of all you are not using the correct key it should be a GlobalKey<FormFieldState>(), but even then the reset() would not work.

The reason for this is because of the implementation of DropdownButtonFormField:

DropdownButtonFormField({
  // ...

  T? value,

  // ...
}) : super(
      // ...

      initialValue: value,

      // ...
     );

(source: Flutter Documentation)

As you can see the value property of DropdownButtonFormField is what defines the initialValue of the FormField so when you are rebuilding your form field and changing the value of etSkillScore1 it is also changing the value of your DropdownButtonFormField.initialValue.

Solution 1

If you want your reset() to work then you can remove the property value of DropdownButtonFormField so the initialValue won't change with etSkillScore1.

DropdownButtonFormField<int>(
  key: etSkillScore1Key,
  decoration: const InputDecoration(labelText: 'Select value'),
  onChanged: (val) {
    etSkillScore1 = val;
    FocusScope.of(context).requestFocus(FocusNode());
  },
  // value: etSkillScore1,
  items: priorities2.map((db.Priority priorities) {
    return DropdownMenuItem<int>(
      child: Text(priorities.name),
      value: priorities.value,
    );
  }).toList(),
)

Try the full example on DartPad

Solution 2

Do not set the value property with etSkillScore1, if you want to initialize your widget with an initial value then do it like this:

DropdownButtonFormField<int>(
  key: etSkillScore1Key,
  decoration: const InputDecoration(labelText: 'Select value'),
  onChanged: (val) {
    etSkillScore1 = val;
    FocusScope.of(context).requestFocus(FocusNode());
  },
  value: 1, // Use a fixed value that won't change
  items: priorities2.map((db.Priority priorities) {
    return DropdownMenuItem<int>(
      child: Text(priorities.name),
      value: priorities.value,
    );
  }).toList(),
)

As your value will be fixed then when DropdownButtonFormField is rebuild it will keep 1 as its initial value.

FLUTTER
SHARE: