'How to change FormBuilderDropdown selected value using setState?

I have the following FormBuilderDropdown from flutter_form_builder definition for user to select US state

class _StateFormBuilderDropdownState extends State<StateFormBuilderDropdown> {
  @override
  Widget build(BuildContext context) {
    return FormBuilderDropdown(
      attribute: widget.attribute,
      initialValue: widget.initialValue,
      validators: [FormBuilderValidators.required()],
      decoration: InputDecoration(labelText: "State (required)"),
      hint: Text('Select State'),
      items: List<DropdownMenuItem>.from(
        UsStates.states.map((s) => DropdownMenuItem(
          value: s.code, child: Text(s.name)
        ))
      ),
      onChanged: widget.onChanged
    );
  }
}

When I get to this screen, I do a reverse geocoding to autofill user address.

When the address is resolved, I call setState to change form values. The problem is that FormBuilderDropdown only have initialValue available to set the value and, as far I know, this is not evaluated again after the first build so I can't use it to change the value.

How can I change FormBuilderDropdown after initial setup?



Solution 1:[1]

I think you can use UniqueKey(). In my case, i need to programmatically reset formbuildercheckboxlist value if using initialValue.

I posted it on another post

Solution 2:[2]

Reset the Dropdown to prevent error due to the setting a different list which is not having the current value in it.

//Create key    
final _dropDownKey = GlobalKey<FormBuilderFieldState>();
            
//Reference the key
FormBuilderDropdown(key:_dropDownKey)
            
//Then reset using the key where ever you want
_dropDownKey.currentState!.reset();
_dropDownKey.currentState!.setValue(null);

//Then you can safely assign a different list of values to the drop down

Solution 3:[3]

How about making use of Keys to force Flutter to re-initialize the FormBuilderDropdown? Simply adding key: const Key(widget.initialValue.toString()) should make it so that the FormBuilderDropdown goes through initState every time widget.initialValue changes, as if it's a completely new widget.

Solution 4:[4]

You can use ValueListenableBuilder to rebuild FormBuilderDropdown when value changes.

  ValueNotifier notifier;

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: notifier,
      builder: FormBuilderDropdown(
          attribute: widget.attribute,
          initialValue: notifier.value,
          validators: [FormBuilderValidators.required()],
          decoration: InputDecoration(labelText: "State (required)"),
          hint: Text('Select State'),
          items: List<DropdownMenuItem>.from(UsStates.states.map(
              (s) => DropdownMenuItem(value: s.code, child: Text(s.name)))),
          onChanged: (value) => notifier.value = value),
    );
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TijaniRF
Solution 2
Solution 3 Ovidiu
Solution 4 Kahou