https://kotlinlang.org logo
#compose
Title
# compose
s

Steffen Funke

11/25/2021, 6:40 AM
Hello, is there any best practice to return a
State<T>
AND a
StateFlow<T>
, backed by the same changing data, at the same time from an Android ViewModel? I have some View based UI which consumes the data as
StateFlow
, and some Compose UI, which would need
State
. And ideally I don’t want to rewrite the Compose part to
collectAsState()
, rather just have it consume State directly from ViewModel (e.g. hide the implementation details inside ViewModel):
Copy code
Inside ViewModel:
    // is consumed by View based UI
    protected val _itemsFlow = MutableStateFlow<List<Item>>(emptyList())
    val itemsFlow = _itemsFlow.asStateFlow()

    // should be consumed by Compose UI
    val items: State<List<Item>> = itemsFlow.collectAsState() // not working bc. of missing @Composable scope
    val items: State<List<Item>> = itemsFlow.collectAsState(emptyList()) // also not working
z

Zoltan Demant

11/25/2021, 6:43 AM
You could use
State<T>
over
StateFlow<T>
in your ViewModel, if thats a viable option for you?
s

Steffen Funke

11/25/2021, 6:44 AM
Hm, mind you have an example how to use
mutableStateOf(List<T>)
inside VM, and get an
StateFlow<List<T>>
out of it 🤔 ?
z

Zoltan Demant

11/25/2021, 6:46 AM
I meant completely replacing StateFlow with State, heres a relevant discussion!
🙏 1
👋 1
s

Steffen Funke

11/25/2021, 6:48 AM
I know I can use State inside viewModel, but my old View part would need this data then as StateFlow… how to do the exposing from State to StateFlow, if I am using State inside VM (which I would prefer as well)? Sorry I think I have some blockage at the moment …
Might
SnapshotFlow
be a way to convert mutablestate to StateFlow? Have to read about it.
Hm, am I on the right track here? At least the data types are fine now 🙂 But is
itemsFlow
updating, when
items
are?
Copy code
// Inside VM
var items by mutableStateOf(emptyList<Item>())
        protected set
    
val itemsFlow = snapshotFlow { items }
👌 3
z

Zoltan Demant

11/25/2021, 6:53 AM
I dont know if this is a good idea:
Copy code
class StateExample<State>(initial: State) {

    private val state = MutableStateFlow(initial)

    val composableState
        @Composable
        get() = state.collectAsState()
}

@Composable
fun Test(example: StateExample<String>) {
    val state by example.composableState
    
    state // <- String!
}
s

Steffen Funke

11/25/2021, 11:23 AM
Thanks all,
snapshotFlow
was the missing piece to convert a
mutableStateOf
into
StateFlow<T>
, see above. Working now! 🥳
👍 1
👍🏽 1
j

Jaime

11/26/2021, 1:54 AM