Hello, is there any best practice to return a `Sta...
# compose
s
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
You could use
State<T>
over
StateFlow<T>
in your ViewModel, if thats a viable option for you?
s
Hm, mind you have an example how to use
mutableStateOf(List<T>)
inside VM, and get an
StateFlow<List<T>>
out of it 🤔 ?
z
I meant completely replacing StateFlow with State, heres a relevant discussion!
🙏 1
👋 1
s
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
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
Thanks all,
snapshotFlow
was the missing piece to convert a
mutableStateOf
into
StateFlow<T>
, see above. Working now! 🥳
👍 1
👍🏽 1
j