I have a list view in my app, I have written some of the code for each item of the list view in the widget containing the list view itself but for the other part I have defined a new child widget. When I try deleting the last element of this list from inside the child widget of the list item, flutter gives me a range error.
RangeError (RangeError (index): Invalid value: Valid value range is empty: 0)
The interesting part is, if I try deleting the item in the list through the code inside the parent widget itself, I don't get an error. This is the parent widget:
class _TodosState extends State<Todos> {
TodosDB _todosdb = GetIt.I.get();
List<Todo> _todos = [];
_loadTodos() async {
final todos = await _todosdb.getAllTodos();
setState(() => _todos = todos);
}
_deleteTodo(int todoId) async {
await _todosdb.deleteTodo(todoId);
_loadTodos();
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return Column(
children: [
Container(
height: screenHeight * 0.6,
width: screenWidth * 0.9,
child: ListView.builder(
itemCount: _todos.length,
itemBuilder: (BuildContext context, int index) {
return OpenContainer(
useRootNavigator: true,
transitionDuration: const Duration(milliseconds: 500),
closedBuilder: (context, action) {
return Row(
children: [
Text(_todos.elementAt(index).taskName),
IconButton(
tooltip: "Delete tag",
onPressed: () {
//this doesn't give an error
_deleteTodo(_todos.elementAt(index).id);
},
icon: const Icon(
Icons.delete,
color: Color.fromARGB(255, 99, 99, 99),
),
),
],
);
},
openBuilder: (context, action) {
return InputModal(
action: action,
deleteTodo: _deleteTodo,
todo: _todos.elementAt(index),
time: widget.time,
timeType: widget.timeType,
index: index,
);
},
);
}),
),
],
);
}
}
This is the child widget:
class _InputModalState extends State<InputModal> {
@override
Widget build(BuildContext context) {
return Container(
color: const Color(0xffBA99FF),
padding: const EdgeInsets.fromLTRB(20, 40, 5, 20),
child: Column(
children: [
IconButton(
onPressed: () {
//this gives me a range error
widget.deleteTodo(widget.todo!.id);
widget.action.call();
},
tooltip: "Delete this task",
icon: const Icon(
Icons.delete,
size: 30,
),
),
],
),
);
}
}
I assume that after deleting the item from the child widget, the state of the list which is provided to the list view in the parent widget doesn't get updated. How can I make sure this doesn't happen?
CodePudding user response:
may be do _deleteTodo(_todos.elementAt(index).id); same in children widget as we have already passed index...
CodePudding user response:
The UI is not rebuilding upon deleting an item from the child. Please add a setState
callback in your delete method.
_deleteTodo(int todoId) async {
await _todosdb.deleteTodo(todoId);
_loadTodos();
setState((){});
}