Dropdown value can not be set null

I implemented two dropdowns. when I select state and district its is working fine. when I change state it is showing me an error. Setting district dropdown value null in getDistricts() method. Please help and thanks in advance.

getting this error in Console:

There should be exactly one item with [DropdownButton]'s value: 1. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value 'package:flutter/src/material/dropdown.dart': Failed assertion: line 828 pos 15: 'items == null || items.isEmpty ||value == null || items.where((DropdownMenuItem item) { return item.value == value; }).length == 1'

class AddAddress extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AddAddressPage();
  }
}

class AddAddressPage extends StatefulWidget {
  @override
  _AddAddressPageState createState() => _AddAddressPageState();
}

class _AddAddressPageState extends State<AddAddressPage> {
  bool loader = false;
  int intState;
  int intDistrict;
  List<Location> districts=listDistricts;
  List<Location> states=listStates;
  getDistricts()async{
    setState(() {
      loader=false;
    });
  List<Location> district= await service.getDistrictsByStateId(intState);
   setState(() {
     districts=district;
      loader=false;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Address"),
        backgroundColor: Colors.white,
        centerTitle: true,
      ),
      body: Stack(
        children: <Widget>[
          SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.only(top: 10.0, left: 30, right: 30),
              child: Form(
                child: Container(
                  child: Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(top: 15.0),
                        child: DropdownButtonFormField<int>(
                            decoration: InputDecoration(
                              contentPadding:
                                  const EdgeInsets.only(left: 30, right: 10),
                              border: OutlineInputBorder(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(15))),
                            ),
                            hint: Text('state'),
                            value: intState,
                            items: states.map((location) {
                              return new DropdownMenuItem<int>(
                                child: Text(location.name),
                                value: location.id,
                              );
                            }).toList(),
                            onChanged: (int value) {
                              setState(() {
                                intState = value;
                             intDistrict=null;
                              getDistricts();
                              });

                            }),
                      ),
                     Padding(
                        padding: const EdgeInsets.only(top: 15.0),
                        child: DropdownButtonFormField<int>(
                            decoration: InputDecoration(
                              contentPadding:
                                  const EdgeInsets.only(left: 30, right: 10),
                              border: OutlineInputBorder(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(15))),
                            ),
                            hint: Text(' district'),
                            value: intDistrict,
                            items: districts.map((location) {
                              return new DropdownMenuItem<int>(
                                child: Text(location.name),
                                value: location.id,
                              );
                            }).toList(),
                            onChanged: (int value) {
                              intDistrict = value;
                            }),
                      ),

                    ],
                  ),
                ),
              ),
            ),
          ),
          ProgressLoader(
            loader: loader,
          )
        ],
      ),
    );
  }
}

this is happening

Upvotes: 0

Views: 6114

Answers (4)

guguCara
guguCara

Reputation: 29

But and if we need to use String myItem; so value:myItem will be null to allow use the hint: Text('select')? We can't use a string that wasnt inicialized, so cant be null but in the same time hint only work if we have a null for value = myItem. Not make sense to me.

Upvotes: 0

wiredmartian
wiredmartian

Reputation: 307

For anyone struggling with this, you need to set a default value for your district. So that (1) dropdown is never empty, (2) dropdown value will always match at least 1 item's value if districts come from, say API as an empty array.


int intDistrict = 999; /// example

List<Location> district= await service.getDistrictsByStateId(intState);

/// set a default district on getDistricts()
district.add(Location(name = "select district", id: 999));
   setState(() {
     districts=district;
      loader=false;
    });


/// when you change to a new state, set intDistrict to default
onChanged: (int value) {
   setState(() {
      intState = value;
      intDistrict = 999;
      getDistricts();
});

Upvotes: 0

Thanks for the help guys. I found the issue.since I upgraded the flutter SDK(not Stable SDK) in dropdown.dart file there ares some changes with the previous. So I compared with the stable SDK and modified the file. Thanks for your time and help guys.

Upvotes: -1

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27137

I think the problem is that as you select new state you are just setting intDistrict value to null while District dropdown has dropdownitems, so i think if you clear districts before setting intDistrict to null then it should work.

 onChanged: (int value) {
            setState(() {
          intState = value;
          districts.clear(); // added line
          intDistrict=null;
          getDistricts();
      });
    }),

Upvotes: 2

Related Questions