https://kotlinlang.org logo
#orbit-mvi
Title
# orbit-mvi
j

Jacob Rhoda

09/20/2023, 8:55 PM
Is there a way to model the input to a view model, such that it’s constant no matter what the state is? Right now I am using a sealed class with an abstract property, but that feels cumbersome.
Copy code
sealed class FmisCropZonePickerState {
    abstract val input: FmisCropZonePickerInput
    data class Loading(override val input: FmisCropZonePickerInput) : FmisCropZonePickerState()
    data class Error(
        val cause: Throwable,
        override val input: FmisCropZonePickerInput
    ) : FmisCropZonePickerState()

    data class State(
        override val input: FmisCropZonePickerInput,
        val cropZones: List<FmisCropZone>,
        val selectedCropZone: FmisCropZone?
    ) : FmisCropZonePickerState()
}
t

twisterrob

09/22/2023, 12:04 PM
you don't need to make it abstract, but then you lose `data`:
Copy code
class FmisCropZonePickerInput
class FmisCropZone

sealed class FmisCropZonePickerState(
	val input: FmisCropZonePickerInput
) {
	class Loading(
		input: FmisCropZonePickerInput
	) : FmisCropZonePickerState(input)

	class Error(
		val cause: Throwable,
		input: FmisCropZonePickerInput
	) : FmisCropZonePickerState(input)

	class State(
		input: FmisCropZonePickerInput,
		val cropZones: List<FmisCropZone>,
		val selectedCropZone: FmisCropZone?
	) : FmisCropZonePickerState(input)
}
Why do you need the input to be always available?
j

Jacob Rhoda

09/22/2023, 12:53 PM
Hmm, that would work but you loose the benefit of immutable state.
I want the input always available because it’s stuff that realistically never changes. Say, the ID of an item that was selected for a detail view.
t

twisterrob

09/22/2023, 1:17 PM
data
doesn't lose immutability,
val
gives you that.
I would store it in a separate "state" in the VM. If you say it never changes, that means it can be even injected in the VM constructor as a
val
.
j

Jacob Rhoda

09/22/2023, 1:18 PM
Ah, I overlooked the val for the input. But you do lose that convenient
copy
method, right?
t

twisterrob

09/22/2023, 1:19 PM
yep
if you wanna stay with one state and cannot inject it construction time, this could be an option so that the responsibilities don't mix:
Copy code
class FmisCropZonePickerInput
class FmisCropZone
data class FmisCropZonePickerVMState(
	val input: FmisCropZonePickerInput,
	val state: FmisCropZonePickerState,
)
sealed class FmisCropZonePickerState {
	data object Loading : FmisCropZonePickerState()

	data class Error(
		val cause: Throwable,
	) : FmisCropZonePickerState()

	data class State(
		val cropZones: List<FmisCropZone>,
		val selectedCropZone: FmisCropZone?
	) : FmisCropZonePickerState()
}
it might be a classic composition over inheritance thing