'How to init a sealed-class in MutableStateFlow

I have a sealed-class like this

sealed class LoadState {
    class Loading : LoadState()
    class Success : LoadState()
    class Fail : LoadState()
}

I use sealed-class with LiveData, it works

open class BaseViewModel: ViewModel() {
//    val loadState by lazy {
//        MutableLiveData<LoadState>()
//    }
    val loadState by lazy {
        MutableStateFlow(LoadState())
    }
}

but when I change MutableLiveData to MutableStateFlow, I get a warning like this

Sealed types cannot be instantiated

so, how to use sealed-class in MutableStateFlow?



Solution 1:[1]

For using MutableStateFlow with sealed class , you can do something like this : Step 1 : Create a sealed class .

sealed class LoadState {
    object Loading : LoadState()
    object Success : LoadState()
    object Fail : LoadState()
}

And then use them in the following way


    private val mutableStateFlow : MutableStateFlow<LoadState?> = MutableStateFlow(null)
    val stateFlow : StateFlow<LoadState?> get() = mutableStateFlow

You can listen to the mutableStateFlow in the following way. In the OnViewCreated of your fragment :

viewLifecycleOwner.lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {

                viewModel.stateFlow.collect { viewState ->
                    when (viewState) {
                       is Loading ->{//do something}

                       is Success ->{//do something}

                       is Fail->{//do something}
                       
                    }
                }
            }
        }

In this way you do not need to specify an initial method everytime . This is how you can use sealed class with mutableState Flow

Solution 2:[2]

You have to choose your initial state

open class BaseViewModel: ViewModel() {
    val loadState by lazy {
        MutableStateFlow(LoadState.Loading()) <-- for example, initial is loading
    }
}

and also, use data class inside sealed class.

sealed class LoadState {
    data class Loading() : LoadState()
    data class Success() : LoadState()
    data class Fail() : LoadState()
}

Solution 3:[3]

Just write your sealed class name as a stateFlow value type, example:

val state = MutableStateFlow<SealedClassName>(SealedClassName.AnySubclassOrObject)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Karunesh Palekar
Solution 2
Solution 3