Best way to pass multiple lambda functions in Kotlin to handle success/failure

For this specific case, when the second lambda is optional, infix functions work very well:

sealed class DeviceStatusResult {
    abstract infix fun onFailure(handler: (String) -> Unit)
}

class DeviceStatusSuccess(val device: Device) : DeviceStatusResult() {
    override fun onFailure(handler: (String) -> Unit) = Unit
}

class DeviceStatusFailure(val errorMessage: String) : DeviceStatusResult() {
    override fun onFailure(handler: (String) -> Unit) = handler(errorMessage)
}

fun getDeviceStatus(onSuccess: (Device) -> Unit): DeviceStatusResult {
    // get device status
    // if (success)
    val device = Device()
    onSuccess(device)
    return DeviceStatusSuccess(device)
    // else
    // return DeviceStatusFailure(message)
}

Then it can used like

getDeviceStatus { device ->
    println(device)
} onFailure { errorMessage ->
    System.err.println(errorMessage)
}

Maybe onFailure should be called orFail or something like that.

It is good when the second argument is optional, but not so much otherwise because it doesn't force the user to actually supply a failure handler. And I don't think it's a good idea because it will be too easy to accidentally omit a failure handler. It's much better to force the user to provide one, even if it happens to be an empty one. Therefore, it is better to use named arguments for this case, even though nothing forces to actually name them.


For example we have a class which needs to have more than one function such as two functions as parameter:

class TestClass internal constructor(
  private val onClickShowName: (String) -> Unit,
  private val onClickShowSurname: (String) -> Unit
) { //Your work. }

Then you need to create val as TestClass:

class MainActivity {
    val mTestClass = TestClass(
        onClickShowName = {dataText: String -> Log.i("CANER", dataText)},
        onClickShowSurname = {dataText: String -> Log.i("CANER", dataText)}
    )
}

You can attach a name to each variable in kotlin. Change your code like this

DeviceService.getDeviceStatus(
                onSuccess = { w ->
                    print("device")
                },
                onFailure = { e -> print(e) })

Tags:

Android

Kotlin