DEV Community

Ritwik Jamuar
Ritwik Jamuar

Posted on

Jetpack Compose + MVI - Part 1: Side Effects

Previously, I had introduced the mechanics of a MVI + Redux Design Pattern and implemented it as an example.

The UI is DaVinci-esque ¬‿¬ but has one problem: Button does nothing.

We would make the click of Button to emulate a REST API Response. This would mean that UI should show progress or some indicator that operation is ongoing.

To emulate a REST API Call, we need a Repository:

fetchSomething() provides a Boolean flag that indicates whether fetching was success or not.

Now, since performing REST API Call is considered side-effect, we create a MiddleWare to handle such side-effect, and here comes ExampleMiddleWare.

Enter MiddleWare

To recap, the purpose of MiddleWare is to handle side-effects (or Action that does not make sense to a Reducer). MiddleWare uses store to propagate another Action, whose processing is upto Reducer or another MiddleWare in the Store.

But before we start shaping the MiddleWare for our example, we must add actions that triggers the execution of this MiddleWare and prompts to change the state once the MiddleWare is finished.

This means adding some actions in already existing ExampleAction:

Now, we implement our MiddleWare as below:

Take a look at the method onButtonClicked().

Whenever we receive an intent that Button is clicked, we perform REST API Call.

To make user aware of such, we propagate an action to Show Loading, and when the value is collected, we propagate an action to Hide Loading.

In order for our MiddleWare to work, we must incorporate it to Store in the MVIViewModel:

Because we wish to update our UI whenever Showing or Hiding progress is propagated, we add a field in our State to support that.

Next, we update our Reducer to accommodate for new Actions, i.e. showing and hiding Progress

Back to UI

So, we add a Progress Bar to our screen using LinearProgressIndicator. To add some animating effect, wrapped the LinearProgressIndicator under AnimatedVisibility.

This results in our UI to look like this:

Side-Effects revisited

Above is one demonstration of handling REST API Call as side-effect.

But remember, MiddleWare does not have to propagate any action.

Here are some examples that does not propagate anything:

1 : Logging

We want to log our Action and State of our Store for logging and debugging purposes. Logging is again another use case of side-effect, which then translates to MiddleWare as below:

This MiddleWare is general-purpose in nature and can be used with any Store.

2 : Navigation

Navigating to another Activity/Fragment can also be thought of as a side-effect, which can be translated to a MiddleWare as below:

The lambda onNavigate is handled by consumer for them to figure out on what action and state they perform navigation.

Takeaways

The point is, MiddleWare can be thought of as a silo that is designed for a singular or a set of purpose.

Meanwhile Reducer has one role and one role only: For a given Action that is considered state changing, Reducer reduces current State to a new one.

Next post, will be a discussion around Testing.

Thank You!

Top comments (0)