There is function collectAsState()
applicable to a StateFlow
property in order to observe it in a Composable
.
A composable requires a StateFlow
because StateFlow
guarantees an initial value. A Flow
doesn't come with that guarantee.
Now, what is the way to go if I have a StateFlow
property but I want to apply an operator (like map
) before collecting the Flow
in the Composable
?
Here an example:
Let's say a repository exposes a StateFlow<MyClass>
val myClassStateFlow: StateFlow<MyClass>
data class MyClass(val a: String)
... and a view model has a dependency on the repository and wants to expose only the property a
to its Composable
...
val aFlow = myClassState.Flow.map { it.a } // <- this is of type Flow<String>
The map
operator changes the type from StateFlow<MyClass>
to Flow<String>
.
- Is it semantically justified that
aFlow
has no initial value anymore? After all its first emission is derived from the initial value ofmyClassStateFlow
. - It's required to convert
Flow
back intoStateFlow
at some point. Which is the more idiomatic place for this?- In the view model using
stateIn()
? How would the code look like? - In the composable using
collectAsState(initial: MyClass)
and come up with an initial value (althoughmyClassStateFlow
had an initial value)?
- In the view model using