0
votes

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

3
could you please provide a fully reproducible code example?Jonathan Rhein
update the code.Please check @Jonisai raja prasanth Chintalapudi
it is still not fully reproducible. Reproducible means that I just have to copy your code into an empty 'main.dart' file and it is compiling and running without me having to fix all sorts of 'undefined name' errors etc. first. Please refer to this guide (stackoverflow.com/help/minimal-reproducible-example) for more help.Jonathan Rhein
​class​ ​Location​ { ​final​ ​String​ name; ​final​ ​int​ id, countryId, stateId, districtId, mandalId; ​Location​( {​this​.name, ​this​.id, ​this​.countryId, ​this​.stateId, ​this​.districtId, ​this​.mandalId}); ​factory​ ​Location​.​fromJson​(​Map​<​String​, ​dynamic​>​ json) { ​return​ ​Location​( name​:​ json[​'name'​], id​:​ json[​'id'​], countryId​:​ json[​'countryId'​], stateId​:​ json[​'stateId'​], districtId​:​ json[​'districtId'​], mandalId​:​ json[​'mandalId'​], ); } } .This is all I can give.sai raja prasanth Chintalapudi
Because I use network call.@Joni please help me.sai raja prasanth Chintalapudi

3 Answers

0
votes

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();
      });
    }),
0
votes

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();
});
-1
votes

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.