Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting type mismatch when using sealed class with rxjava in kotlin

I have following code

sealed class AddressUiState
object AddressLoading : AddressUiState()
class AddressLoadedState(val addressResponse: AddressBookResponse) : AddressUiState()
class AddressErrorState(val error: Throwable) : AddressUiState()

and I have ViewModel like below

class AddressViewModel constructor(private val service: SingleProfileService) : ViewModel() {

    fun getDisplayableAddressState(id: String): Observable<out AddressUiState> {
        return service.getAddresses(id)
                .map { AddressLoadedState(it) }
                .startWith(AddressLoading)
                .onErrorReturn { AddressErrorState(it) }
                .subscribeOn(Schedulers.io())

    }
}

I'm seeing the compilation error and onErrorReturn with error Type mismatch. Required: AddressLoadedState! found: AddressErrorState What is wrong with above code?

like image 216
Veeresh Kalmath Avatar asked Jun 26 '18 07:06

Veeresh Kalmath


1 Answers

in your code

.map { AddressLoadedState(it) }

gives a

Observable<AddressLoadedState>

The onError function expects a Function that takes an exception and returns something that extends T.

Observable<T> onErrorReturn(Func1<? super Throwable, ? extends T> resumeFunction)

In this case, T is AddressLoadedState. AddressErrorState does not extend this, so the compiler will complain.

You could split the statements into more than one line to help the compiler though, to show it T is actually a AddressUiState. Or you can also tell the compiler on the map function itself like this:

    return service.getAddresses(id)
            .map<AddressUiState> { AddressLoadedState(it) }
            .startWith(AddressLoading)
            .onErrorReturn { AddressErrorState }
            .subscribeOn(Schedulers.io())
like image 66
Bruce Lowe Avatar answered Oct 20 '22 16:10

Bruce Lowe