Rak
12/01/2021, 8:35 PMMikolaj Leszczynski
12/02/2021, 7:23 AMwhen
. It can get complicated. It might be worth extracting the reducers if that’s the case.
I think someone over here used https://github.com/Tinder/StateMachine with such an approach to make it more manageable. This increases complexity and indirection so it has its downsides too.
TL;DR no perfect solution for this exists :)appmattus
12/03/2021, 10:46 AMGuilherme Delgado
12/03/2021, 10:54 AMdata class
to control the state changes (reduce) I’ve used a FSM (that one from Tinder) to help “connecting”. Small example:
ViewModel:
//entry point called from View
fun start() { stateMachine.transition(TimerState.Event.OnStart) }
//state machine
state<TimerState.State.Idle> {
...
on<TimerState.Event.OnStart> {
transitionTo(TimerState.State.CountingDown, TimerState.SideEffect.StartCountDown)
}
}
...
onTransition {
...
when (val effect = validTransition.sideEffect) {
...
is TimerState.SideEffect.StartCountDown -> play()
}
}
//state change
private fun play() {
intent { ...
reduce { ...
state.play() // state is a data class and play() it's a helper method to change some val values, ex: fun play() = copy(isCountingDown = true, ...)
}
}
}
}
}
Hope it helpsGuilherme Delgado
12/03/2021, 10:54 AMGuilherme Delgado
12/03/2021, 10:55 AMmiqbaldc
12/09/2021, 6:58 AM// in viewmodel
sealed class States {
object Initial : States()
object UserFetched : States()
}
data class VerificationState(
val agent: Agent? = null,
val states: States = States.Initial,
)
// for example, we use Nothing for side-effect
class OurViewModel(
// dependencies
) : ViewModel(), ContainerHost<VerificationState, Nothing> {
override val container: Container<VerificationState, Nothing> = container(initialState = VerificationState())
fun getUser(token: String) = intent {
runCatching {
agentUseCase(token)
}.onSuccess {
it.collect { agent ->
reduce {
state.copy(agent = agent, states = States.UserFetched) // switch the state(s) here
}
}
}.onFailure {
postSideEffect(...) // do something when failures
}
}
the Tinder/StateMachines
seems a good alternative in our parts, thanks @Guilherme Delgado. Might need to checks on it for our usecase and interopability later!
// our Activity
// onCreate
viewModel.observe(this, state = ::render)
private fun render(state: VerificationState) {
when (state.states) {
States.Initial -> {}
States.UserFetched -> successGetUser(state.agent)
}
}
miqbaldc
03/26/2022, 5:23 PMmiqbaldc
03/28/2022, 12:31 AMGuilherme Delgado
03/28/2022, 8:20 AM