Get dropdown values based on another dropdown value in flutter - 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,
),

Related

how can i get my category name when value type is id in dropdown flutter

i am trying to show category name and store category id in database but my categories id are not line by line
My Dropdown button
DropdownButton(
items: categoriesList.map((item) {
return DropdownMenuItem(
child: Text(item['name'].toString()), value: item['id'].toString());
}).toList(),
onChanged: (changedCategoryId) {
setState(() {
print(int.parse(changedCategoryId.toString()));
});
},
hint: Text(selectedCategory),
),
fetch data code
List categoriesList = [];
var selectedCategory = "Select Category";
#override
void initState() {
// TODO: implement initState
fetchCategories();
super.initState();
}
fetchCategories() async {
var fetchedCategoriesList =
await http.get(Uri.parse("${AppConfig.BASE_URL}categories"));
var decodedFetchedCategoriesList =
json.decode(fetchedCategoriesList.body)['data'];
setState(() {
categoriesList = decodedFetchedCategoriesList;
});
print(categoriesList);
}
onChanged: (changedCategoryId) { // this runType is Dropdow
final id = changedCategoryId['id'];
final name = changedCategoryId['name'];
},
you can store the id to database , and show the name on screen

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();
});
}

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(),
)));

Flutter : problem with dropdown_formfield 0.1.1 plugin when put data to second menu

Hello I am working with flutter drop down menu. First menu is for location and second is for sublocation. It is working when clicking on first location but when changed to second and clicking on second location this error appears:
my variable
//location
String _myLocation ;
List data = List();
//sublocation
String _mySublocation ;
List data2 = List();
function for location
getLocation() async {
try{
var res = await http
.get(Uri.encodeFull("http://iraqdoctors.com/api/locations"), headers: {"Accept": "application/json"});
setState(() {
var resBody = json.decode(res.body);
data = resBody;
});
return "Sucess";
}catch(e){
}
}//get location
function for sublocation
getSublocation() async {
try{
var res2 = await http
.post(Uri.encodeFull("http://iraqdoctors.com/api/getlocationflutter"),
headers: {"Accept": "application/json"},
body: {
"cityname":"$_myLocation",
}
);
setState(() {
var resBody2 = json.decode(res2.body);
data2 = resBody2;
});
return "Sucess";
}catch(e){
}
}//get sublocatio
Location dropdown
DropDownFormField(
hintText: 'اختر المدينة',
titleText: null,
value: _myLocation,
dataSource: data,
onChanged: (value) {
setState(() {
_myLocation = value;
getSublocation();
});
},
textField: 'city',
valueField: 'city',
),
Sublocation dropdown
DropDownFormField(
hintText: 'اختر المنطقة',
titleText: null,
value: _mySublocation,
dataSource: data2,
onChanged: (value) {
setState(() {
_mySublocation = value;
});
},
textField: 'state',
valueField: 'state',
),
Replace your _myLocation Dropdown with following code and it will work for you:
DropDownFormField(
hintText: 'اختر المدينة',
titleText: null,
value: _myLocation,
dataSource: data,
onChanged: (value) async { // <-- added async.
_myLocation = value; // <-- updated value outside of setState((){})
await getSublocation(); // <-- Fetched data outside of setState((){})
setState(() { // <-- When every thing is ready setState is called
});
},
textField: 'city',
valueField: 'city',
),
I hope this helps, in case of any doubt please comment. If this answer helps you then please accept and up-vote the answer.