I want to share with you what is in my opinion a perfect, small and concise use case for reactive repository with new Kotlin flow. Before we dive into the problem at hand we first have to have a short introduction to our building blocks: flow and reactive store.
Hopefully by this time all of us have at least heard of flow, but just in case, here is a definition: flow is a library that represents a cold stream of data which is asynchronously computed. We can do lots of different manipulations on the values so it is quite easy to map and filter data in any layer of your app.
Reactive store by Dropbox
This small library is an awesome addition to the Android ecosystem by the guys in dropbox. Basically, what it does, is manage data requests for you, caches the data and returns you the result as flow. I will explain it when we implement it in our little example.
Store docs are awesome and I do recommend that you read them. Just follow this link.
What are we building?
Idea is to build some sort of message inbox that can be opened with multiple screens based on the type of message that you need. Messages can also be deleted on any screen you want which can lead to a lot of boilerplate code needed to handle all the callbacks.
As you can see in this gif. When the app is opened there is a network call for messages with a number of messages and potential categories shown. After opening any of the categories you can read and delete any message. And that is about it, the simplest case to showcase this.
Show me the code
First lets see the repository:
To use Store you need to define a fetcher and use the Store for any dataSource operation. Everything else is handled by the library.
On app start streamQuestions is called and will stay active all the time.
Now for the last and the most important part, read/delete screen.
Depending on what category is picked we have an event channel to inform our flow of changes (only latest info) and we just have to filter a type that we need. Maybe you have noticed, but we are calling streamQuestions() again, which is an unnecessary network call usually, but in this case Store is smart enough to give us cached data from the memory.
Finally, we have our delete operation. In many cases this can add a lot of code and complexity because of data sync issues. Not here!
ViewModel calls delete interaction, which then calls a repository operation. After dataSource (network) is called to delete a message and success is returned (ignoring error for simplicity) the final and crucial step is to inform the store that fresh data needs to be fetched.
And that's it! Fresh data is fetched successfully and dispatched to all active flow channels. Our data is up to date and correctly updated on all screens. Happy times.
Obviously this is far from a real world use case but I think this bare bones example best illustrates the power of reactive programming in a very simple fashion.
Thank you for reading, I hope you found this helpful. Please comment and share if you liked it.