Maestro 💙 Freezed
In a previous blog post I introduced Maestro which is for now an experiment to manage you app state in a Flutter application.
Today I will show you how to use the power of Freezed ⚡️ to create the models and the states. I will not explain in details how this library works but I will show you how easily we can create immutable objects with it!
Freezed is a great library created by Remi Rousselet for generating all the boilerplate code you want for immutable objects and even more!
The source code of today is heavily inspired by an example for another great app state management library called flutter_bloc created by Felix Angelov.
The goal of this app is to show a list of posts which fetches new posts when the user scrolls.
We will focus on 4 components of this app:
- The model (A post)
- The different states of the home page
- The composer which represents the logic
- The home page and its sub widgets
The Model
We have only one model on this app, it’s called Post
. A post contains only an id
, a title
and a body
:
By writing this, we tell freezed to generate the boilerplate code for our immutable object, it will also use json_serializable to generate the code we need to serialize/deserialize into JSON.
We just have to execute the following command in a terminal, and all the code for comparing instances, and deserialize from JSON will be generated:
flutter pub run build_runner build
The States
Our app has three states: an empty initial state, a success state containing the posts we were able to fetch and a boolean indicating whether there is more posts or not, and a failure state in case a problem occurred while fetching the posts.
With freezed we just have to write this and the above command to generate all we want:
The Composer
It contains all our logic, this is the component which does the actual fetch to the server (for simplicity I did not used a Repository
and a Data Source
, which I would have in a real app) and change the state of our app.
We override the method called play
to automatically fetch the first data when the composer is attached to the tree.
The fetch
method will change the state according to the current one:
- If the current state is the initial one, then we have to load the first twenty posts and change the state accordingly
- If the current state is a success one, we have to load twenty more posts, and also change the state to a new success one with the posts from the previous state and the twenty more we got. We use here the copyWith
method generated by freezed to copy the previous state and change only some data.
- If there is an error somewhere, we write a failure state.
The Page
We have only one page in our application. I’m used to separate all the part of my layout in different widgets so that there is one widget by semantical part of the view:
HomePage
This widget is responsible for creating the maestros and the components which don’t need the values of these maestros.
We create a Maestro
for the HomeState
, and we initialize it to the initial
state. We also create a Maestro
for the composer.
_Page
This widget is responsible for listening to the changes of the HomeState
and for returning the right widget according to the type of the current state.
We use another feature of freezed, called map, which, you can see, is very convenient.
_Initial
This is the widget for the initial state. During this state we want to show the user that we’re loading data.
_Success
This is the main widget, which is responsible for displaying successful data.
When there are no posts, we simply show the user an explanatory text, otherwise the app shows a special list which is able to fetch new data, by calling the fetch
method of our composer, when the user scrolls.
_Failure
This is the widget to display when there is a problem.
_Post
This is the widget for an item of the list, responsible for displaying a single Post
.
Conclusion
As you can see, Freezed and Maestro, work very well together. If you want to dive in all the source code, you can find it here. As I explained Maestro is still an experiment, but if you’re interested don’t hesitate to try it and tell me what you think about it. If you find some use cases you don’t find how to manage with Maestro, fill an issue on the repo and we will try to find a solution 😉.