The riverpod (v2) documentation contains two great examples how a TODO-list could be implemented using either a Notifier or an AsyncNotifier. Both examples are functionally equivalent.
To pick one particular detail the non-async example contains a remove method like this
// Let's allow removing todos
void removeTodo(String todoId) {
// Again, our state is immutable. So we're making a new list instead of
// changing the existing list.
state = [
for (final todo in state)
if (todo.id != todoId) todo,
];
}
Whereas the async version looks like this
// Let's allow removing todos
Future<void> removeTodo(String todoId) async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
await http.delete('api/todos/$todoId');
return _fetchTodo();
});
}
I'd now like to modify the async version to remove the deleted TODO item from it's internal state instead of re-fetching the whole collection via HTTP (which is what _fetchTodo does). I guess a practical reason could be to implement something like optimistic updates, but in this case it's rather a learning experience for me.
If I understood correctly, you want to remove a TODO item from the list in the state without re-fetching everything from the API/scratch. In that case:
Assuming you have a List<ToDoItem> listOfTodoItems
inside your state, this is how you'd remove that item:
void updateToDoList(ToDoItem itemToRemove){
//Step 1: find the index of the item we're searching the list for
final indexOfSearchItem = listOfToDoItems.indexWhere((currentToDoItem)=> currentToDoItem == ToDoItem(toDoValue: 'Math class'));
//Step 2: copy the whole list so we can replace the old list with the updated one
final listToUpdate = state.listOfTodoItems;
//Step 3: remove the item from the list we're going to update
listToUpdate.removeAt(indexOfSearchItem);
//Step 4: update the state's list with the new updated list
state = state.copyWith(listOfTodoItems: listToUpdate);
}
Points to note, I directly used Equatable for this, but this could've been done by overriding == operator
and hashCode
methods.
I directly used copyWith
method, again assuming that you already have this in your data class or generated using freezed
package.
I used a simple sample of ToDoListItem
but this idea applies to most of these examples. A more complex situation would be working with nested lists within nested lists in data classes.
This way you're only removing data within state management boundaries and you're not sending/receiving updated ToDoItem's to/from the backend.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With