0

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;
      });
    }
  }
}
Fidz
  • 33
  • 6

0 Answers0