I have an app that uses Kotlin with an MVVM approach. My goal here is to send the state (SUCCESS, FAIL, ERROR, EXCEPTION.VM_INSERT...) from View Model to activity. In my activity, I observe the state and based on that I will inform the user about the state. The SUCCESS, FAIL, ERROR state works as expected, unfortunately, I struggle to find out how show in Activity the exception message send by EXCEPTION.VM_INSERT.
ViewModel State:
sealed class ViewModelState {
sealed class EXCEPTION : ViewModelState() {
class VM_INSERT(val exception: String) : ViewModelState()
class VM_UPDATE(val exception: String) : ViewModelState()
class VM_DELETE(val exception: String) : ViewModelState()
class VM_QUERY(val exception: String) : ViewModelState()
}
object SUCCESS : ViewModelState()
object FAIL : ViewModelState()
object ERROR : ViewModelState()
}
ViewModel:
...
private val _insertWordStatus = MutableLiveData<ViewModelState>()
val insertWordStatus: LiveData<ViewModelState> = _insertWordStatus
fun insertWord(word: Word) = viewModelScope.launch {
try {
val insertedRowId = repository.insertWord(word)
if (insertedRowId > -1) {
_insertWordStatus.value = ViewModelState.SUCCESS
} else {
_insertWordStatus.value = ViewModelState.FAIL
}
} catch (ex: Exception) {
_insertWordStatus.value = ViewModelState.ERROR
_insertWordStatus.value =
ex.localizedMessage.toString()?.let { ViewModelState.EXCEPTION.VM_INSERT(it) }
}
...
Activity:
...
wordViewModel.insertWordStatus.observe(this, Observer { viewModelState ->
if (viewModelState == ViewModelState.SUCCESS ) {
} else if (viewModelState == ViewModelState.FAIL) {
} else if (viewModelState == ViewModelState.ERROR) {
} else {
}
})
...
You forgot to make all the intended children of
EXCEPTION
subclasses ofEXCEPTION
. Also, you should move their shared property into the superclass so you take advantage of inheritance to, for example, log the error without having to check the specific type of EXCEPTION.In my opinion, you should refactor it as follows. I don't think the complexity of a sealed class is justified if every one of its children has identical class structure. That's really fighting against the basic principles of object oriented programming. Example:
By the way, you should look up how to use
when
statements in Kotlin. It is much cleaner than a chain ofelse if
s when they're all checking against the same argument. Example: