Caching Bloc State with “hydrated_bloc”
Hey everyone! In this tutorial, we’re going to give the Weather App we made an upgrade. Instead of always having to start from scratch and enter a city, we’re going to cache the bloc state so that we end up with the following:
Note that after we kill the app it starts right back where it left off. In addition, after it has loaded the previous (cached) state, the app requests the latest weather data and updates seamlessly. Let’s get started!
Featuring Hydrated Bloc
There are many ways we can achieve the above behavior; however, in this tutorial, we’re going to use the new hydrated_bloc package.
hydrated_bloc is an extension to the bloc state management library which automatically persists and restores bloc states.
Setup
The first thing we need to do is add hydrated_bloc as a dependency to the pubspec.yaml
.
Then we need to install it with:
flutter packages get
HydratedBlocDelegate
The next thing we need to do to the weather app is swapped out BlocDelegate
with HydratedBlocDelegate
.
Instead of extending BlocDelegate
we just need to extend HydratedBlocDelegate
and pass a HydratedStorage
instance to the super class.
Next, we need to use our SimpleBlocDelegate
just like before:
Alternatively, if we didn’t want to use our own custom SimpleBlocDelegate
we could simply initialize our delegate like:
The last thing we need to do is update our blocs to extend HydratedBloc
instead of Bloc
.
SettingsBloc
Once we update our SettingsBloc
to extend HydratedBloc
we need to override fromJson
and toJson
in order to tell HydratedBloc
how to serialize/deserialize the states.
In addition, instead of returning a default initialState
we can first try to return the HydratedBloc
's initialState
and if that’s null
then we fall back to our old initialState
.
ThemeBloc
Next, we need to update the ThemeBloc
to also extend HydratedBloc
.
Same thing here: we need to update the ThemeBloc
to extend HydratedBloc
instead of bloc
, update initialState
, and override fromJson
and toJson
.
WeatherBloc
Last but not least is the WeatherBloc
.
You’ll notice that in our toJson
we’re only returning our Map<String, dynamic>
if the state is WeatherLoaded
. This is because if toJson
returns null
, then that state is not persisted. In our case, we don’t want to persist initial, loading, or error states so we omit those and just return null
instead.
That’s all there is to it! 🎉
Now when a user runs the app, it will automatically persist the state changes and allow he/she to kill the app (or hot restart) and pick it up right back where they left off.
The full source for this example can be found here.
If you enjoyed this exercise as much as I did you can support me by ⭐️the repository, or 👏 for this story.