Reputation: 948
I want to get the initial value of the Dropdown button from firebase;
but when I try to set the governorateDDValue = selectedUser.governorate;
inside the build method
the value of Dropdown get the value from firebase but I cannot change it
this my code
class UserInfo extends StatefulWidget {
static const routeName = '/UserInfoScreen';
const UserInfo({Key? key}) : super(key: key);
@override
_UserInfoState createState() => _UserInfoState();
}
class _UserInfoState extends State<UserInfo> {
late User selectedUser;
final date = DateFormat('yyyy-MM-dd').format(DateTime.now()).toString();
var governorateDDValue;
@override
Widget build(BuildContext context) {
final userList= Provider.of<List<User>>(context);
final userID = ModalRoute.of(context)!.settings.arguments as String;
selectedUser =
userList.firstWhere((user) => user.id == userID);
// this line makes dropdown value always equal to value from firestore
governorateDDValue = selectedUser.governorate;
return Scaffold(
appBar: AppBar(
title: Text('report'),
),
body: SingleChildScrollView(
child: Container(
child: Row(
children: <Widget>[
Text('Governorate',),
Container(height: 5),
DropdownButton<String>(
value: governorateDDValue,
icon: const Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
onChanged: (String? newValue) {
setState(() {
governorateDDValue = newValue!;
});
},
items: Constants.governoratesOfEgypt
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
),
),
);
} }
thanks in advance
Upvotes: 2
Views: 87
Reputation: 26
Because you use governorateDDValue = selectedUser.governorate;
inside build widget so the Dropdown menu will reset its value every time you change it
the build widget will rebuild and the value of the dropdown will stay equal to the value from firebase
you should use governorateDDValue = selectedUser.governorate;
outside the build widget
this code should work will
class UserInfo extends StatefulWidget {
static const routeName = '/UserInfoScreen';
const UserInfo({Key? key}) : super(key: key);
@override
_UserInfoState createState() => _UserInfoState();
}
class _UserInfoState extends State<UserInfo> {
var loading = false;
late User selectedUser;
final date = DateFormat('yyyy-MM-dd').format(DateTime.now()).toString();
var governorateDDValue;
@override
void initState() {
super.initState();
loading = true;
print('Future.delayed outside');
print(loading);
Future.delayed(Duration.zero, () {
governorateDDValue = selectedUser.governorate;
setState(() {
loading = false;
});
});
}
@override
Widget build(BuildContext context) {
final userList = Provider.of<List<User>>(context);
final userID = ModalRoute
.of(context)!
.settings
.arguments as String;
selectedUser =
userList.firstWhere((user) => user.id == userID);
// this line makes dropdown value always equal to value from firestore
governorateDDValue = selectedUser.governorate;
return Scaffold(
appBar: AppBar(
title: Text('report'),
),
body: SingleChildScrollView(
child: Container(
child: Row(
children: <Widget>[
Text('Governorate',),
Container(height: 5),
DropdownButton<String>(
value: governorateDDValue,
icon: const Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
onChanged: (String? newValue) {
setState(() {
governorateDDValue = newValue!;
});
},
items: Constants.governoratesOfEgypt
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
),
),
);
Upvotes: 1
Reputation: 480
The reason why you cannot change it is because every time setState
is called your build
method is called. Therefore your value will always be set to governorateDDValue = selectedUser.governorate;
So to allow changes you should place this governorateDDValue = selectedUser.governorate;
in iniState
Or what you can do is like this so that it will only set it once
class UserInfo extends StatefulWidget {
static const routeName = '/UserInfoScreen';
const UserInfo({Key? key}) : super(key: key);
@override
_UserInfoState createState() => _UserInfoState();
}
class _UserInfoState extends State<UserInfo> {
late User selectedUser;
final date = DateFormat('yyyy-MM-dd').format(DateTime.now()).toString();
bool initState = true; // ADD HERE
var governorateDDValue;
@override
Widget build(BuildContext context) {
final userList= Provider.of<List<User>>(context);
final userID = ModalRoute.of(context)!.settings.arguments as String;
selectedUser =
userList.firstWhere((user) => user.id == userID);
// this line makes dropdown value always equal to value from firestore
if(initState){ // ADD HERE
governorateDDValue = selectedUser.governorate;
initState = false; // ADD HERE
}
return Scaffold(
appBar: AppBar(
title: Text('report'),
),
body: SingleChildScrollView(
child: Container(
child: Row(
children: <Widget>[
Text('Governorate',),
Container(height: 5),
DropdownButton<String>(
value: governorateDDValue,
icon: const Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
onChanged: (String? newValue) {
setState(() {
governorateDDValue = newValue!;
});
},
items: Constants.governoratesOfEgypt
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
),
),
);
}
Upvotes: 1