we have a flutter-project running and want to include a stateful widget with a dropdownmenu. We use SQflite as our database.
We have a list of profiles in our database and with the dropdown we want to select one of the profiles. This works fine.
The Problem:
We save the ID of the last profile selected in with SharedPreferences. Initially we want to have the profile with the last selected id (which we load from SharedPreferences) as the default value.
Our Dropdown-Menu inside a future-builder (of the list profilesFuture with type Future<List<Profile>>):
return new Container(
child: DropdownButton<Profile>(
items: snapshot.data.map((Profile item) {
return DropdownMenuItem<Profile>(
value: item,
child: Text(item.caption + " (" + item.serverAddress + ")")
);
}).cast<DropdownMenuItem<Profile>>().toList(),
onChanged: (Profile newSelectedProfile) {
setState(() {
selectedProfile = newSelectedProfile;
PreferencesService.setLastProfileId(newSelectedProfile.id);
});
},
value: selectedProfile,
)
);
We initialize our state like this:
Future profilesFuture;
Profile selectedProfile;
Future prefService;
int lastProfileId;
@override
void initState() {
profilesFuture = DatabaseService.db.getProfiles();
super.initState();
_getLastProfileId().then((value) => _getSelectedProfile(value));
}
Future<Profile> _getSelectedProfile(int id) async {
Profile profile = await DatabaseService.db.getProfileById(id);
setState(() {
selectedProfile = profile;
});
return profile;
}
Future<int> _getLastProfileId() async {
int profileId = await PreferencesService.getLastProfileId();
setState(() {
lastProfileId = profileId;
});
return profileId;
}
The Error
either zero or 2 or more dropdownmenuitems were detected with the same value. Assertion failed. There should be exactly one item with DropDownMenus value.
Further information: https://github.com/glutter-dev-team/glutter/blob/feature/profile-selector/lib/widgets/profile_selector.dart
The Question
Whats wrong with it? How to correctly initialize a DropDownMenu with async values. The Problem definitely is caused by the default value. Without initializing the value-parameter it works fine, but the initial state is not correct.
All we have to do is:
- Load the lastSelectedProfileId from SharedPreferences (async)
- Load the selectedProfile from the database-layer (async)
- Load the list of all profiles from the database-layer (async)
- Set the selectedProfile as default value and the list as dropdownmenu-items
FutureBuilderto theprofilesFuture(the list) around this like mentioned above. - MrzJklProfileclass - pskinkitems.where((DropdownMenuItem<T> item) { return item.value == value; }).length == 1- pskink