Android LiveData Resource: Propagate Data or Exception (Kotlin)

August 19, 2019

Use a Resource object to hold data or exception.

class Resource<out T> private constructor(
    private val data: T?,
    private val error: Throwable?
) {

    val isSuccessful: Boolean
        get() = data != null && error == null

    constructor(data: T) : this(data, null)

    constructor(exception: Throwable) : this(null, exception)

    fun data(): T {
        if (error != null) {
            throw IllegalStateException("Check isSuccessful first: call error() instead.")
        }
        return data!!
    }

    fun error(): Throwable {
        if (data != null) {
            throw IllegalStateException("Check isSuccessful first: call data() instead.")
        }
        return error!!
    }
}

NOTE: Alternative Resource object solution

Usage

val messageLiveData = MutableLiveData<Resource<String>>()
fun getMessage() {
    try {
        // fetch data
        val message = ...
        messageLiveData.value = Resource(message)
    }
    catch (e: Exception) {
        messageLiveData.value = Resource(e)
    }
}
messageLiveData.observe(lifecycleOwner, Observer { event ->
    if (event.isSuccessful) {
        val message = res.data()

        // do something
    }
    else {
        val e = res.error()

        // handle exception
    }
}
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.