'Flutter Form Builder - FormBuilderDropdown does not display correct value on screen

I am creating a form with the plugin flutter_form_builder (https://pub.dev/packages/flutter_form_builder).

When I use FormBuilderDropdown, you can selected a different value, but it won't show you the selected value on screen. Normally you have a value property, but this widget does not have that. It only has an initial value.

Note

When I removed the whole onChanged method, it does show me the right value on the screen. BUT I need this onChanged method so I cannot remove it...

Code from

final shippingPackagesList = [
        {"key": "dhlpwc-parcelshop", "label": "DHL ServicePoint"},
        {"key": "dhlpwc-home", "label": "Thuis bezorgen"},
        {
          "key": "local_pickup:7",
          "label": "Afhalen in de winkel in Heerlen, Limburg"
        },
      ];

return Column(
children: [
FormBuilder(
                          autovalidateMode: AutovalidateMode.always,
                          key: _formKey,
                          child: Column(
                            children: [
                              const SizedBox(height: 5.0),
                              FormBuilderDropdown(
                                  items: shippingPackagesList
                                      .map((shippingPackage) =>
                                          DropdownMenuItem(
                                            value: shippingPackage['key'],
                                            child: Text(shippingPackage['label']!),
                                          ))
                                      .toList(),
                                  name: 'shipping_key',
                                  onChanged: (value) {
                                    String shippingPackageKey =
                                        value.toString();

                                    // Set selected shipping method in cart view model

                                    cartViewModel
                                        .setSelectedShippingPackageByString(
                                            shippingPackageKey);
                                    cartViewModel.updateTotalCosts();
                                  },
                                  // initialValue: "dhlpwc-parcelshop",
                                  hint: Text("Kies verzendmethode"),
                                  decoration: const InputDecoration(
                                    border: OutlineInputBorder(
                                        borderRadius:
                                            BorderRadius.all(Radius.zero)),
                                    contentPadding: EdgeInsets.all(8.0),
                                  )),
                              const SizedBox(height: 10.0),
                            ],
                          )),
Text(
                          '€ ${cartViewModel.selectedShippingPackage!.totalCost.toStringAsFixed(2)}',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                          ),
                        ),
]
)

How can I solve this problem? Or is this a bug?

EDIT

Cart view model functions

class CartViewModel extends ChangeNotifier {

// Properties
ShippingPackage? _selectedShippingPackage;
double? _totalWithShippingPrice;
// Getters
ShippingPackage? get selectedShippingPackage => _selectedShippingPackage;
double? get totalWithShippingPrice => _totalWithShippingPrice;

void setSelectedShippingPackageByString(String shippingPackageKey) {
    for (var shippingPackage in cart!.shippingPackages) {
      if (shippingPackage.key == shippingPackageKey) {
        _selectedShippingPackage = shippingPackage;
      }
    }
    notifyListeners();
  }

void updateTotalCosts() {
    double total =
        cart!.totals.articlesWithTax + selectedShippingPackage!.totalCost;
    _totalWithShippingPrice = total;
    notifyListeners();
  }
}

Main

@override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CartViewModel()),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'App',
        home: Scaffold(
          body: MyMainHome(),
        ),
      ),
    );
  }

Pubspec yaml

add provider: ^6.0.2 in pubspec.yaml



Solution 1:[1]

I experimented with the flutter_form_builder and the FormBuilderDropdown specifically. Writing this code based on the example of the package:

class Home72124205 extends StatefulWidget {
  const Home72124205({Key? key}) : super(key: key);

  @override
  State<Home72124205> createState() => _Home72124205State();
}

class _Home72124205State extends State<Home72124205> {
  List<String> locationsList = [
    'New York',
    'Tokyo',
    'London',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FormBuilderDropdown(
          name: 'location',
          decoration: const InputDecoration(
            labelText: 'Location',
          ),
          initialValue: locationsList.first,
          allowClear: true,
          onChanged: (value){
            print(value);
          },
          items: locationsList
              .map((location) => DropdownMenuItem(
                value: location,
                child: Text(location),
              )).toList(),
        ),
      ),
    );
  }
}

I was not able to reproduce your issue. The widget works as intended. The label on the dropdown changes, the onChange gets called and the code gets executed.

As we don't have access to your full application, I am unable debug your issue.

Are you able to experiment with this example and test if, within the context of your application, the problem still happens?

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 João Soares