Reactive stream with Flow

Pankaj Rai 🇮🇳
ProAndroidDev
Published in
4 min readAug 24, 2022

--

Have you ever thought about having a reactive flow in your app to update the content instantly or a flow of the stream which updates the content as and when available, for example, observing the network state or even getting the response from the API calls?
In coroutines, a flow is a type that can emit multiple values sequentially, as opposed to suspending functions that return only a single value.

Well with Kotlin Flow we can add the reactive stream to the android app, let’s check out various ways to create Flow and also the features that it offers.

Flow Builder
One of the most common ways to create flow is with the flow builder flow {}

As compared to the normal function now simple function is going to return a stream of values one by one, so the output for this will be

Well, so far we have seen a very simple case of returning the value with the collect terminal operator. What happens if collect is called twice, do that will provide the current ongoing value or it will restart the flow — the simple answer is that it will restart the flow as it’s a cold stream that means body inside flow builder does not run until the flow is collected.

Operators play a very vital role in Flow so let’s see a few of the various types of operators.

Intermediate Operators
Just like the collections here even flow can be transformed with operators like map or filter. These types of operators act on the upstream flow and provide results through the downstream flow.

Here map operator is transforming the result from Int to String that will eventually be collected using the collect terminal operator. In a similar way if we just need to show the even numbers along with the map then we can add a filter above the map like this

Transform Operator
With the transform operator, we can emit arbitrary values an arbitrary number of times.

Output to this codebase is

Size-limiting Operator
Not all the times we will need values an arbitrary number of times instead it may be fixed to a certain number. With the size limiting operator, we can stop emitting the value once the size is reached for eg

Here even though the flow builder has the potential to emit values from 1 to 10 still the output will remain till 1 to 5 as we have specified with take() operator to only allow receiving value 5 times.

So far we have seen the intermediate operator — the operator which holds the tendency to transform the result but that will not emit or deliver the result until and unless a terminal operator is used. You might have observed that in all the code snippets collect{} is used at the end, that’s actually one of the terminal operators. Let’s see the various type of terminal operators.

Terminal Operator
They are the suspending functions that start a collection of the flow as flow are cold stream, hence if you forget to add this operator then it will not even execute the body of the flow builder. Following are the terminal operator that you can use with flow

  1. toList(), toSet() — Converts to the collections.
  2. first and single — Operators to get the first value and with single ensure that flow emits a single value.
  3. reduce and fold — Reducing a flow to a value
  4. collect — Fetching the value emitted by the flow

Let’s see a few of the terminal operators in action

first terminal operator
The overall objective of this operator is to return the first element emitted by the flow and then cancel the flow’s collection.

This will provide the result as 1 as we have specified first() operator that will cancel the flow’s collection after fetching the first result.

single terminal operator
It awaits for one and only one value to be emitted and throws NoSuchElementException for empty flow and IllegalStateException for flow that contains more than one element.

reduce terminal operator
Accumulates value starting with the first element and applying the operation to current accumulator value and each element.

This will print the result as 55
Here with reduce, it keeps the old and current value on which we can perform some operation like here it’s addition operation.

fold terminal operator
Here the operation starts with the default value and then acts on the current provided value.

This will print the result as 155
The reason why it’s having 155 as result is that the initial value was set to 100.

collect terminal operator
It’s one of the most commonly used operators that collects the emitted values from the flow builder. It can also be used by chaining other operators like onEach, onCompletion and catch.

Here the output will be

Even the various types of intermediate operators that we have seen earlier can also be used before calling the collect terminal operator.

That’s it in this article where we have seen how to get started with Flow and the various types of operators that it offers, now in the next article, we will see about the context, buffering, conflating result etc.

--

--