kotlin-workshop

Kotlin Workshop - Chennai

View on GitHub

Sealed Classes

Sealed classes are, in a sense, extension of Enum classes.

enum class BasicScreenState {
    ERROR,
    LOADING,
    DATA
}

Let’s say we are fetching some data async from the network and we are tracking our UI screen state using the above enum during the fetch.

fun setBasicScreenState(basicScreenState: BasicScreenState) {
    when(basicScreenState) {
        BasicScreenState.ERROR -> { /* set error state in the view */ }
        BasicScreenState.LOADING -> { /* set loading state in the view */ }
        BasicScreenState.DATA -> { /* hide loading or error states in the view */ }
    }
}

fun displayData(someData: SomeData) {
    // actually display the data in the view
    //sometextView.text = someData.name
}

We are calling 2 functions to handle our success state setBasicScreenState() and displayData().

What if we wanted to hold someData in the enum itself to handle the success case in the when expression above and avoid call to displayData(). It would look something like this.

enum class ScreenStateField(val someData: SomeData) {
    ERROR(SomeData("1", "some data 1")),
    LOADING(SomeData("2", "some data 2")),
    DATA(SomeData("3", "some data 3"))
}

But here we have to create Error, Loading states with dummy SomeData assuming we are fetching it from network.

We can achieve this using Sealed classes and when expressions

sealed class ScreenState {
    data class Error(val errorMessage: String) : ScreenState()
    data class Loading() : ScreenState()
    data class Data(val someData: SomeData) : ScreenState()
}

fun setScreenState(screenState: ScreenState) {
    when(screenState) {
        is ScreenState.Error -> { /* set error state in the view */ }
        is ScreenState.Loading -> { /* set loading state in the view */ }
        is ScreenState.Data -> {
            /* hide loading or error states in the view and display data*/
            //sometextView.text = screenState.someData.name
        }
    }
}