Reputation: 17
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,
)
],
),
);
}
}
Upvotes: 0
Views: 6114
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
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
Reputation: 17
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
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