how can get radio value in Flutter? - flutter

how can get radio value in Flutter?
I writing this code and tring to get value, but has a little problems.
Code
enum SingingCharacter { Australia, USA }
SingingCharacter? _character = SingingCharacter.Australia;
String res = await AuthMethods().signUpUser(
email: _emailController.text,
password: _passwordController.text,
username: _usernameController.text,
bio: _bioController.text,
file: _image!,
country: _character.toString(),
);
Column(
children: <Widget>[
RadioListTile<SingingCharacter>(
title: const Text('Australia'),
value: SingingCharacter.Australia,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
RadioListTile<SingingCharacter>(
title: const Text('USA'),
value: SingingCharacter.USA,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
],
),
When the use register and choose the country, I will got this value SingingCharacter.Australia and writing firebase, but I hope I could got like this value Australia or USA, not got SingingCharacter.Australia or SingingCharacter.USA
Where is my falut code?

You have given the RadioListTile<T> where T as SingingCharacter. So you will get the value as SingingCharacter.USA or SingingCharacter.Australia. If you want only the name, try like below.
onChanged: (SingingCharacter? value) {
setState(() {
if (value != null) {
_character = value;
String enumValue = value.name; // USA
// or
enumValue = describeEnum(value); // USA
}
});
}
https://api.flutter.dev/flutter/foundation/describeEnum.html

For a flexible solution, perhaps you can leverage extension, something like this:
enum SingingCharacter { Australia, USA }
extension SingingCharacterExt on SingingCharacter {
String get code {
switch (this) {
case SingingCharacter.Australia:
return "AU";
case SingingCharacter.USA:
return "US";
}
}
}
Usage:
debugPrint(SingingCharacter.Australia.code);

Related

How to Set Default Value by Condition in DropdownButtonFormField in Flutter?

I Have DropdownButtonFormField as Below.
CaseReasonModel? dropdownValueCaseReason;
List<DropdownMenuItem<CaseReasonModel>> items = [];
dropDownModels.forEach((element) {
items.add(DropdownMenuItem(
child: Text(
element.reasonName!,
style: Themes.getTextStyle(context),
),
value: element,
));
});
DropdownButtonFormField<CaseReasonModel>(
style: Themes.getTextFieldTextStyle(context),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context).hintSelectCaseReason,
),
value: dropdownValueCaseReason,
isExpanded: true,
items: items,
onChanged: (value) {
setState(() {
dropdownValueCaseReason = value;
});
},
),
And CaseReasionModel Class as below.
class CaseReasonModel {
String? reasonName;
String? reasonId;
String? reasonStatus;
static CaseReasonModel? fromHashMap(dynamic map) {
if (map == null) return null;
CaseReasonModel result = new CaseReasonModel();
result.reasonName = map["name"];
result.reasonId = map["reasonId"].toString();
result.reasonStatus = map["status"];
return result;
}
static List<CaseReasonModel> fromArrayOfHashMap(dynamic jsonArray) {
List<CaseReasonModel> list = [];
if (jsonArray != null) {
for (var jsonObject in jsonArray) {
list.add(fromHashMap(jsonObject)!);
}
}
return list;
}
}
I got all Reason in Drop-down, So here i have to set default selected value based on reason id which i specified. Suppose i have to set value which id = 2,
so how can I do this ?.

Flutter: struggle with async functions

What I want to do is to load users and put them in a list. I am doing this with the function getUsers().
After that I want to load an Event (with fetchEvent()) which is a table with some dropdown menus.
My problem is that the users are sometimes not there when the event gets loaded. Thats why dropdown button is disabled.
I tried to solve this with using "then".
This is my initState:
void initState() {
besetzungsList.clear();
if (widget.eventId != null) {
getUsers().then((_) => fetchEvent());
} else
getUsers();
print(widget.eventId);
super.initState();
}
This is getUsers()
getUsers() async {
getCurrentUser();
usersStream = authBloc.getUsers();
usersStream.listen((allUsers) {
for (ApplicationUser user in allUsers) {
if (user.userRoleList.contains(team)) users.add(user.username);
}
});
}
fetchEvent() async {
...
dataTableRows.add(DataRow(
cells: [
DataCell(
Text(event.dienstMap["Aufgabe"][i]),
onTap: () {
removeRow(i);
},
),
DataCell(
Text(event.dienstMap["Zeit"][i]),
onTap: () {},
),
DataCell(
Text(event.dienstMap["Team"][i]),
onTap: () {},
),
DataCell((i > event.dienstMap["Besetzung"].length - 1 == true)
? DropDown(
hint: "Wählen",
users: users,
besetzungsListChanged: (String value) {
if (besetzungsList.length > 0) {
besetzungsList.removeAt(i);
}
besetzungsList.insert(i, value);
},
fromDropDown: (bool value) => fromDropDown = value,
)
: DropDown(
hint: event.dienstMap["Besetzung"][i],
users: users,
besetzungsListChanged: (String value) {
besetzungsList.removeAt(i);
besetzungsList.insert(i, value);
},
fromDropDown: (bool value) => fromDropDown = value,
))
],
));
}
});
setState(() {});
}
You can add that fetchEvent in your stream listener, so that it will get called after adding the user object to the array. Since it's a stream if you get a new user object, it will again call that fetchEvent and update your dropdown values.
Future<void> getUsers() async {
getCurrentUser();
usersStream = authBloc.getUsers();
usersStream.listen((allUsers) {
for (ApplicationUser user in allUsers) {
if (user.userRoleList.contains(team)) {
users.add(user.username);
}
}
await fetchEvent();
});
}

Get dropdown values based on another dropdown value in flutter

I have a url that returns a json of companies, i use the list of companies to fill a dropdown. there is another url with a parameter that returns a list of warehouses. The second method that gets the warehouses returns an empty json.
Here is the code that gets the companies. This is working alright
String? _mySelection;
final String url = "http://url:8000/companies"
Future<String> getCompanies() async {
var res = await http
.get(Uri.parse(url), headers: {
'Content-Type': 'application/json'
});
var resBody = json.decode(res.body)["data"]; // data = map["data"];
print(resBody);
setState(() {
data = resBody;
});
print(res);
return "Sucess";
}
The code that gets the warehouses is similar.
Future<String> getWarehouses(company) async {
late String warehousesUrl = "http://myWarehouseurl?company=$company";
var warehouseRes = await http
.get(Uri.parse(warehousesUrl), headers: {
'Content-Type': 'application/json'
});
var warehouseResBody = json.decode(warehouseRes.body)["data"]; // data = map["data"];
print(warehouseResBody);
setState(() {
warehouseData = warehouseResBody;
});
print(warehouseRes);
return "Sucess";
}
And my initState method
#override
void initState() {
super.initState();
this.getCompanies();
this.getWarehouses(_mySelection);
}
The dropdowns
new DropdownButton(
items: data.map((item) {
return new DropdownMenuItem(
child: new Text(item['company_name']),
value: item['company_name'].toString(),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_mySelection = newVal.toString();
getWarehouses(_mySelection);
});
},
value: _mySelection,
),
_mySelection != "" ? DropdownButton(
items: warehouseData.map((item) {
return new DropdownMenuItem(
child: new Text(item['warehouse_name']),
value: item['name'].toString(),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_mySelection = newVal.toString();
});
},
value: _mySelection,
) : Container(),
I am not sure why i am unable to get the values for the second dropdown, when i call the method to get the values for the warehouse in the onchange method in the companies dropdown, the data from the warehouses are printed to the console, but the app crushes.
I think you miss the async/await, lets try
new DropdownButton(
items: data.map((item) {
return new DropdownMenuItem(
child: new Text(item['company_name']),
value: item['company_name'].toString(),
);
}).toList(),
onChanged: (newVal) async{ // here need the change
setState(() {
_mySelection = newVal.toString();
await getWarehouses(_mySelection); // also here add the await
});
},
value: _mySelection,
),

How to reset second drop down list if i change first drop down value?

I have two drop down which second is depends on first.
When i changing the first drop down value after selecting second dropdown value it throws an error as below.
So how to reset second drop down list if i changing first drop down value?
Drop down buttons are as below.
DropdownButtonFormField<Standard>(
validator: (value) {
if (value == null) {
return "Select Standard";
}
},
isExpanded: true,
hint: Text('Select Standard'),
value: selectedStandard,
items: _standards.map((Standard standard) {
return DropdownMenuItem<Standard>(
value: standard,
child: Text(standard.standardName),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedStandard = val;
standardId = val?.standardId;
onMediumChange(val);
});
}),
SizedBox(height: 20),
DropdownButtonFormField<Medium>(
validator: (value) {
if (value == null) {
return "Select Medium";
}
},
isExpanded: true,
hint: Text('Select Medium'),
value: selectedMedium,
items: _mediums.map((Medium medium) {
return DropdownMenuItem<Medium>(
value: medium,
child: Text(medium.mediumName),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedMedium = val;
mediumId = val?.mediumId;
});
}),
And get Values code is as below. Varibles which i used.
var _standards = <Standard>[];
var _mediums = <Medium>[];
Standard? selectedStandard;
Medium? selectedMedium;
#override
void initState() {
super.initState();
ApiManager().getStandards().then((standards) {
setState(() {
_standards = standards;
});
});
}
void onMediumChange(standard) {
setState(() {
selectedStandard = standard;
_mediums = [];
});
String mediumUrl =
"$baseUrl/medium/get_by_course_id?standard_id=${selectedStandard?.standardId}";
ApiManager().getMediums(mediumUrl).then((List<Medium> value) => {
setState(() {
_mediums = value;
})
});
}
As I understand there is a problem with selectedMedium
Try change Make it selectedMedium null inside onMediumChange
void onMediumChange(standard) {
setState(() {
selectedMedium = null;
selectedStandard = standard;
_mediums = [];
});
String mediumUrl =
"$baseUrl/medium/get_by_course_id?standard_id=${selectedStandard?.standardId}";
ApiManager().getMediums(mediumUrl).then((List<Medium> value) => {
setState(() {
_mediums = value;
})
});
}
first, check the values in _mediums because you must have a different value of selectedMedium here as according to this error !!!

Creating dynamic dropdown - Flutter Issue Items reads zero

Hello I tried to create a dynamic dropdown with flutter. the request to end point returns the data successfully but the DropdownButtonFormField items array is reading zero. it is not getting the data at all. Please can any one help me?
Dropdown menu items variable:
List<DropdownMenuItem> _anchorLists = List<DropdownMenuItem>();
dynamic _selectedAnchor;
void initState() {
super.initState();
_getAnchorsByProvider();
}
The Function:
_getAnchorsByProvider() async {
try {
_prefs = await SharedPreferences.getInstance();
var _anchorService = AnchorService();
var result = await _anchorService
.getAnchorsByProviderId(_prefs.getInt('providerOid'));
var anchors = json.decode(result.body);
anchors.forEach((anchor) {
setState(() {
_anchorLists.add(DropdownMenuItem(
child: Text(anchor['acronym']),
value: anchor['oid'],
));
});
});
setState(() {
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
return e.toString();
}
}
The Dropdown
SizedBox(height: 20),
(_anchorLists.length > 0)?
DropdownButtonFormField(
value: _selectedAnchor,
items: _anchorLists,
hint: const Text('Select your Anchor'),
onChanged: (value) {
setState(() {
_selectedAnchor = value;
});
},
)
: Text('Loading'),
Result
Values of the json:
{
"oid": 1,
"acronym": "MAAN",
"contactAddress": "Abuja",
"idCardInstruction": null,
}
Because you are retrieving a json object (Map) and not a json list (List), forEach must iterate through key and value pairs, like so:
anchors.forEach((key, value) {
_anchorLists.add(DropdownMenuItem(
child: Text(value.toString()),
value: value.toString(),
));
});
I'm not sure of the specifics of your needs so tweak accordingly, but if you only wish to provide specific values, you can specify like so:
_anchorLists.addAll([anchors['acronym'], anchors['oid']]
.map((value) => DropdownMenuItem(
child: Text(value.toString()),
value: value.toString(),
)));