Showing this error when trying to onChange. Basically it doesn't allow to set the state. Using another dropdown alike this that is working fine.
class GetCitiesAndRestaurants {
List<Cities> _cities;
List<RestaurantTypes> _restaurantTypes;
List<Cities> get cities => _cities;
List<RestaurantTypes> get restaurantTypes => _restaurantTypes;
GetCitiesAndRestaurants({
List<Cities> cities,
List<RestaurantTypes> restaurantTypes}){
_cities = cities;
_restaurantTypes = restaurantTypes;
}
GetCitiesAndRestaurants.fromJson(dynamic json) {
if (json["cities"] != null) {
_cities = [];
json["cities"].forEach((v) {
_cities.add(Cities.fromJson(v));
});
}
if (json["restaurantTypes"] != null) {
_restaurantTypes = [];
json["restaurantTypes"].forEach((v) {
_restaurantTypes.add(RestaurantTypes.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
if (_cities != null) {
map["cities"] = _cities.map((v) => v.toJson()).toList();
}
if (_restaurantTypes != null) {
map["restaurantTypes"] = _restaurantTypes.map((v) => v.toJson()).toList();
}
return map;
}
}
/// id : 1
/// restaurantTypeName : "Arabian"
class RestaurantTypes {
int _id;
String _restaurantTypeName;
int get id => _id;
String get restaurantTypeName => _restaurantTypeName;
RestaurantTypes({
int id,
String restaurantTypeName}){
_id = id;
_restaurantTypeName = restaurantTypeName;
}
RestaurantTypes.fromJson(dynamic json) {
_id = json["id"];
_restaurantTypeName = json["restaurantTypeName"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["id"] = _id;
map["restaurantTypeName"] = _restaurantTypeName;
return map;
}
}
class Cities {
int _id;
String _cityName;
int get id => _id;
String get cityName => _cityName;
Cities({
int id,
String cityName}){
_id = id;
_cityName = cityName;
}
Cities.fromJson(dynamic json) {
_id = json["id"];
_
cityName = json["cityName"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["id"] = _id;
map["cityName"] = _cityName;
return map;
}
}
This is modal class used to get response from server. the below same code for generating other list from server is working But this is not working
DropdownButtonFormField(
decoration: InputDecoration(
isDense: true,
labelStyle: formMiniStyle,
labelText: 'City',
),
value: _selectedCity,
onChanged: (newValue) {
setState(() {
_selectedCity = newValue;
});
},
items: fromServer.data.cities.map((city) {
return DropdownMenuItem(
child: Text(city.cityName),
value: city.cityName,
);
}).toList(),
)
The above code generates the particular error on change the dropdown value
class CreateBranch extends StatefulWidget {
@override
_CreateBranchState createState() => _CreateBranchState();
}
class _CreateBranchState extends State<CreateBranch> {
Future<GetCitiesAndRestaurants> getCitiesAndRestaurants;
var _selectedCity;
Future<GetCitiesAndRestaurants> fetchCitiesAndRestaurants() async {
//print(token);
Map<String, String> headers = {
'Content-Type': 'application/json',
'Accept': 'text/plain',
"Authorization": "Bearer $token"
};
final response = await http.post(
"${BaseUrl}",
headers: headers,
body: jsonEncode({}) //requesting to post empty json
);
print(response.statusCode);
if (response.statusCode == 200) {
return GetCitiesAndRestaurants.fromJson(jsonDecode(response.body));
}
}
@override
void initState() {
super.initState();
getCitiesAndRestaurants = fetchCitiesAndRestaurants();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<GetCitiesAndRestaurants>(
future: getCitiesAndRestaurants,
builder: (BuildContext context, fromServer) {
if(fromServer.hasData){
return Container(
width: MediaQuery.of(context).size.width,
height: (MediaQuery.of(context).size.height),
//color: Colors.grey[200],
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.only(top: 25, right: 25, left: 25),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Restaurant profile image"),
Text("Inactive",
style: TextStyle(
color: Color(0xff35C1F2),
fontSize: 13,
fontWeight: FontWeight.bold)),
],
),
SizedBox(
height: 10,
),
Stack(
children: [
Container(
width: 50,
height: 50,
margin: EdgeInsets.only(right: 30),
child: _image == null
? Image(
image: AssetImage(
"assets/Bitmap.png",
),
)
: Image.file(
_image,
fit: BoxFit.cover,
),
),
Positioned(
left: 60,
bottom: 5,
child: GestureDetector(
onTap: getImage,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: kPrimaryColor,
borderRadius:
BorderRadius.circular(5)),
child: Icon(
Icons.edit,
color: Colors.white,
size: 18,
)),
),
)
],
),
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
flex: 1,
child: TextFormField(
onChanged: (text) {
setState(() {
branchNameEnglish = text;
});
},
decoration: InputDecoration(
isDense: true,
labelStyle: formMiniStyle,
labelText: 'Branch name',
),
),
),
SizedBox(
width: 20,
),
Expanded(
flex: 1,
child: DropdownButtonFormField(
decoration: InputDecoration(
// suffixIconConstraints: ,
labelStyle: formMiniStyle,
labelText: 'Restaurant Type',
),
value: _restaurantType,
onChanged: (newValue) {
setState(() {
_restaurantType = newValue;
});
},
items: fromServer.data.restaurantTypes.map((restType) {
return DropdownMenuItem(
onTap: (){
fromServer.data.cities.map((e) => print(e.cityName));
setState(() {
restaurantId = restType.id;
});
},
child: Text(restType.restaurantTypeName),
value: restType,
);
}).toList(),
)
),
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 25),
child: TextField(
onChanged: (text) {
setState(() {
location = text;
});
},
decoration: InputDecoration(
isDense: true,
labelStyle: formMiniStyle,
labelText: 'Location',
suffixIcon: IconButton(
onPressed: openGoogleMap,
icon: Icon(
Icons.location_on_outlined,
)),
),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
flex: 1,
child: TextFormField(
onChanged: (text) {
setState(() {
landmark = text;
});
},
decoration: InputDecoration(
labelStyle: formMiniStyle,
labelText: 'Landmark',
),
),
),
SizedBox(width: 20,),
Expanded(
flex: 1,
child: DropdownButtonFormField(
decoration: InputDecoration(
isDense: true,
labelStyle: formMiniStyle,
labelText: 'City',
),
value: _selectedCity,
onChanged: (newValue) {
setState(() {
_selectedCity = newValue;
});
},
items: fromServer.data.cities.map((city) {
return DropdownMenuItem(
child: Text(city.cityName),
value: city.cityName,
);
}).toList(),
)
),
],
),
),
SizedBox(height: 50),
Column(children: [
Text("Please contact Jahezlee for subscription charges",
style: TextStyle(
fontSize: 13,
color: Color(0xffE35F21),
fontWeight: FontWeight.bold)),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("+964 23467581",
style: TextStyle(
fontSize: 13,
color: Color(0xffE35F21),
fontWeight: FontWeight.bold)),
Text("[email protected]",
style: TextStyle(
fontSize: 13,
color: Color(0xffE35F21),
fontWeight: FontWeight.bold)),
],
)
]),
LayoutBuilder(builder: (context, constraints){
if(constraints.maxWidth > 500){
return SizedBox(height: 100,);
}else{
return SizedBox(height: 60,);
}
}),
],
),
),
);
}else if(fromServer.hasError){
return Text("Something Went wrong");
}
return Center(
child: Container(
width: 35,
height: 35,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color> (kPrimaryColor),
)),
);
},
),
),
);
} }
The problem is here:
value: _selectedCity,
onChanged: (newValue) {
setState(() {
_selectedCity = newValue;
});
},
value=_selectedCity
is where the error is coming from, because _selectedCity
is null as you didn't initialize it. You must initialize it with a default value so that value
won't be null
.
Like this: var _selectedCity = defaultValue;
otherwise with just var _selectedCity;
, _selectedCity
would be null
.
Update
My next guess is, from the error message, it tells you that there is more than one DropdownMenuItem
that has the same value, so try checking your values again so there are no duplicates.
items: fromServer.data.cities.map((city) {
return DropdownMenuItem(
child: Text(city.cityName),
value: city.cityName, // duplicated values here maybe!
);
}).toList(),