Completing the Reactive Architecture

We have our database, and our repository now offers a reactive and asynchronous API for working with the data. However:

For example, right now, RosterListFragment only needs the list of to-do items. However, that is very simplistic. Most UIs are more complex than that. Even in the scope of this book, this is too simple. Later on, we will add filtering into the app, so the user can restrict the output to only show a subset of the items. Similarly, we could add searches, so the user could find items that match some search expression. Now, we need to keep track of filter modes, search expressions, and so on, in addition to the items to be displayed. And, as we move into asynchronous operations, we will want to track whether or not we are working on loading the data, so we can show some sort of progress indicator while that is going on. And so forth.

To help deal with that complexity, rather than having our motors keep track just of items, we will have them emit “view-state” objects. The view-state represents the data needed to render the UI. The fragments will observe those view-states and update their UIs to match, based on what is in those states.

This idea of a “view-state” is part of implementing a unidirectional data flow architecture. In this style of UI development, UI actions trigger updates to repositories, where those updates in turn trigger new view-states to be emitted, which trigger changes to the UI itself:

Unidirectional Data Flow Architecture
Unidirectional Data Flow Architecture

This is a continuation of the work we did in the previous tutorial. The book’s GitLab repository contains the results of the previous tutorial as well as the results of completing the work in this tutorial.

Step #1: Defining a Roster View State

Next, let’s create a RosterViewState class to represent our view-state for our RosterListFragment. Since this will be a small class that is tightly tied to RosterMotor, we can take advantage of Kotlin’s support for multiple classes in a single source file, to reduce clutter in our project tree a bit.

So, in RosterMotor, above the RosterMotor class itself, add this class:

data class RosterViewState(
  val items: List<ToDoModel> = listOf()
)

This just holds onto our list of to-do items, though over time we will add other properties to this class.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.