Hey guys, I’m here again to talk about another component of the bloc pattern ecosystem. Today we are going to talk a little bit about replay_bloc, a component of the bloc that gives us a state time machine.
With it you can effortlessly implement the Undo functionality, which allows the user to return to the previous state, for example when he regrets performing a certain action.
This post is more recommended if you have a certain familiarity with flutter_bloc. It is a way to manage the state of your app, if you want to know a little more, you can go deeper into the very complete documentation here https://bloclibrary.dev/#/.
Without further ado, let’s go to the code.
The project that will be done as an example is an app to create Todos. Basically there will be a screen where the user sees a list of Todos and can create Todos by pressing a FAB. Todos will be created with a random description and with the isDone property also created at random. This property is responsible for indicating whether the Todo is finished or not.
There will be a trash icon that the user can press to delete a Todo. After a Todo has been deleted, a Snackbar will be displayed informing you of the deletion of the Whole, and with the option to make Undo of the operation. By clicking on Undo, the recently deleted Todo will be recovered again.
After creating our project, we need to add the dependencies we use. In this simple example we only need the 4 dependencies below.
The first 3 packages are from the flutter_bloc ecosystem and the faker package is what we will use to generate boolean and string values at random.
After that we can create our Todo model.
We can then create our TodoCubit. We will define our Todo State abstract class. It is important that our abstract class has a list of Todos, as we will need to control this list of Todos in all the states that our Cubit goes through.
After that we can define our states of success that will be issued after creating a new Todo and after deleting some Todo.
Note that both states also receive a list of Todos as a parameter and need to pass these Todos to the abstract class we defined earlier.
After we have defined the possible states for our cubit, we will now actually implement the methods that will emit these states.
Let’s start with the method that adds a new Todo. He will basically create a new Todo, using Faker to generate the information at random. After creating the new Todo, we simply add it to the Everyone list and issue the TodoAddSuccess status, passing the new Everyone list as a parameter.
The deletion method is even simpler. We simply delete from the list of Todos o Todo passed as a parameter and issue the status TodoDeleteSuccess, passing as a parameter the new list of Todos.
With that we were able to implement all the logic to create and remove our Todos. Let’s start now to write our Widgets to interact with TodoCubit.
And finally, we will be able to implement the Undo function after deleting a Todo.
The first widget that we will create is our TodoListPage. It is basically a wrapper that creates a TodoListView providing a TodoCubit.
Our TodoListView is the widget that actually shows a list of every Todo. Note that when you press the FAB, the method that adds a Todo is called and a new Todo is created.
In the listener of the BlocConsumer we wait for the TodoDeleteSuccess state and when it is emitted, we show a SnackBar on the screen with a message and an option to make Undo in the operation. Here is where the whole MAGIC happens.
The only thing we need to do to get back to the previous state is to call our cubit’s undo method. In doing so, cubit will be responsible for reemitting the previous state. As the previous state still had the Todo deleted on its Todos list, we were able to successfully recover the Todo that was deleted with minimum effort.
You can see the behavior on the gif above:
Just to complete the example, we see below the TodoList widget, which is a ListView that displays all Todos.
That’s it for today guys. The complete source code for the example is below: https://github.com/rodrigobastosv/todo_undo
Thank you very much. Be safe!