I have a page for item insert and inside it a DropdownButton contains list of categories to select from. Then there is a button beside it you use to add a new category into the dropdown items without reload the page "image below"
dropdown with IconButton beside
The problem that when I add a new category am facing an error as the following "RangeError (index): Invalid value: Not in range 0..10, inclusive: 11".
The error appears for a seconds in the UI "this red error box" before it disappear. My guess is that it happen because the count of the items inside the DropdownButton is changes before the rebuild happen.
I searched for such thing but I can't find any solution plus there is no "count" property for the DropdownButton like the "listView Builder" to help me, all the available solutions is for the listView and not related to the DropdownButton.
code in the dorpdown:
class AndroidDropdown extends StatefulWidget {
final List dropDownData;
final Function getSelectedValue;
//valueFromDB: used for the edit case, when there is already saved value
final int valueFromDB;
AndroidDropdown(
{@required this.dropDownData,
@required this.getSelectedValue,
this.valueFromDB});
@override
_AndroidDropdownState createState() => _AndroidDropdownState();
}
class _AndroidDropdownState extends State<AndroidDropdown> {
String _selectedValue;
int prevValueFromDB;
@override
void initState() {
super.initState();
//check if there a data from the DB (for update reasons)
if (widget.valueFromDB != null) {
int listIndex = widget.valueFromDB - 1;
_selectedValue = widget.dropDownData[listIndex];
widget.getSelectedValue(widget.valueFromDB);
prevValueFromDB = widget.valueFromDB; //to use in checkIfNewValueAdded()
} else {
//make the default selected is the first value
_selectedValue = widget.dropDownData[0];
//assign a default value for the function in case the user didn't use onChange
widget.getSelectedValue(1);
}
}
@override
Widget build(BuildContext context) {
checkIfNewValueAdded();
List<DropdownMenuItem<dynamic>> dropdownItems = [];
//the items loop function
for (var item in widget.dropDownData) {
var newItem = DropdownMenuItem(
child: Text(item),
value: item,
);
dropdownItems.add(newItem);
}
return DropdownButton<dynamic>(
value: _selectedValue, //for initial value
items: dropdownItems,
onChanged: (value) {
setState(() {
_selectedValue = value;
widget.getSelectedValue(widget.dropDownData.indexOf(value) + 1);
//I used this trick to get the ID of the item type that saved in the DB
});
},
);
}
//this to check if there is a new value added in the list
void checkIfNewValueAdded() {
if (widget.valueFromDB != prevValueFromDB) {
setState(() {
int listIndex = widget.valueFromDB - 1;
_selectedValue = widget.dropDownData[listIndex];
prevValueFromDB = widget.valueFromDB;
});
}
}
}