> For the complete documentation index, see [llms.txt](https://android-course.cornellappdev.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://android-course.cornellappdev.com/chapters/8.-flows.md).

# 8. Flows

In Kotlin, a `Flow` is an asynchronous stream of values. Values will flow down the stream, and there are collectors that can observe these values. `Flow` is probably best explained by example, so let's go over some common use-cases for `Flow`s in Android Development

## Example 0: Pure flow example

```kotlin
class NewsRemoteDataSource(
    private val newsApi: NewsApi,
    private val refreshIntervalMs: Long = 5000
) {
    val latestNews: Flow<List<ArticleHeadline>> = flow {
        while(true) {
            val latestNews = newsApi.fetchLatestNews()
            emit(latestNews) // Emits the result of the request to the flow
            delay(refreshIntervalMs) // Suspends the coroutine for some time
        }
    }
}
```

Here we have a very pure example of how a `Flow` can be used. I took this from [creating a flow](https://developer.android.com/kotlin/flow#create) on the Android developer documentation since it is a very nice first flow usage example. Here we use `flow` , which is a flow builder that allows us to run `suspend` functions inside and `emit` their results to the flow. We could observe this flow using `latestNews.collect` , so then whenever the `emit` function is called, the lambda we pass in to `latestNews.collect` is also called. Let's see how we could observe this `Flow` in the UI.&#x20;

```kotlin
val latestNewsState: State<List<String>> =
            newsRemoteDataSource.latestNews.collectAsState(initial = listOf())

        Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
            LazyColumn {
                items(latestNewsState.value) {
                    Text(text = it)
                }
            }
        }
```

We can use the `collectAsState` method. `collect` is a method on a Flow that suspends the code block until the `FlowCollector` finishes emitting values. In this case, our `FlowCollector` is the `while(true)` block from the first code snippet, so `collect` block suspends indefinitely. However, `collectAsState` runs `collect` in a coroutine and transforms the results into a `State<List<String>>`, and as we know whenever the `State` value changes, our UI recomposes and automatically updates. This is one of the benefits of reactive UI. So even though running a lambda on each flow value emission is a more of an imperative idea, we can still use it in a reactive (declarative) context.

## Example 1: Account creation validation

&#x20;Let's say that the user is typing in their account information, and we want the UI to update *live* based on whether their information is valid. This could be if their email is valid, if their password is secure enough, etc.. But for this demo, we're going to do a basic version with just username and password. Let's walk through the ViewModel code to see how it uses `Flow` to streamline this idea.&#x20;

{% code title="MainScreenViewModel.kt" %}

```kotlin
data class UiState(
    val username: String = "",
    val password: String = "",
    val isValid: Boolean = false,
)

@HiltViewModel
class MainScreenViewModel @Inject constructor(
) : ViewModel() {
    private val password = MutableStateFlow("")
    private val username = MutableStateFlow("")

    private val _uiState = MutableStateFlow(UiState())
    val uiState = _uiState.asStateFlow()

    init {
        combine(username, password) { username, password ->
            val isValid = username.isNotBlank() && password.length > 8
            _uiState.update {
                UiState(
                    username,
                    password,
                    isValid,
                )
            }
        }.launchIn(viewModelScope)
    }

    fun updatePassword(newPassword: String) {
        password.update { newPassword }
    }

    fun updateUsername(newUsername: String) {
        username.update { newUsername }
    }
}
```

{% endcode %}

Let's walk through this code. You'll first notice that `password` and `username` are `MutableStateFlow`s. A `MutableStateFlow` is a type of `Flow` that holds a state, and it emits new values whenever its state is updated. You may be wondering, *why not just use a state to represent these values*? The main reason is that we want to be able to launch an operation whenever either of these values updates. States are automatically observed by the UI, since whenever a state's value changes the UI recomposes. But we don't have a good way of observing state updates ourselves. `Flow` emissions however are easily observed through the `combine` function. Whenever the `username` or `password` flows have an emission, the `combine` function is called, and we update the `UiState` accordingly.&#x20;

So we use `combine` to create a new `Flow` that is a result of applying the transform functions to the values from the emissions of `username` and `password`. The thing is, the `combine` method alone just initializes this new `Flow`, but it doesn't actually `collect` it, so the transform lambda we wrote won't be called. That's why we use `launchIn`, which `collect`s the flow in a certain `CoroutineScope`. We use `viewModelScope` , so when our ViewModel gets disposed, our coroutine will get disposed with it. and we don't have a memory leak where we are using resources to constantly observe this `Flow`.

Some other design decisions for this ViewModel include making all the `MutableStateFlow`s private. This was done for separation of concerns, so we don't have to worry about the UI updating our ViewModel flows however they want to. The only functions that mutate the state that we expose to the UI are `updatePassword` and `updateUsername` , so now we know exactly where updates to this ViewModel's state will be coming from: usages of those functions. We expose the uiState with `asStateFlow`, which makes it read-only.&#x20;
