You can use the built-in stdlib (starting with Kotlin 1.1) takeIf() or takeUnless either work:
obj?.toString().takeUnless { it.isNullOrBlank() }?.let { doSomethingWith(it) } // or obj?.toString()?.takeIf { it.isNotBlank() }?.let { doSomethingWith(it) } // or use a function reference obj?.toString().takeUnless { it.isNullOrBlank() }?.let(::doSomethingWith)
To perform the doSomethingWith() action on the final value, you can use apply() to work in the context of the current object and return is the same object, or let() to change the result of the expression, or run() to work in the context of the current object , as well as change the result of the expression or also() execute the code when the original object is returned.
You can also create your own extension function if you want the naming to be more meaningful, for example nullIfBlank() might be a good name:
obj?.toString().nullIfBlank()?.also { doSomethingWith(it) }
which is defined as an extension to a nullable String :
fun String?.nullIfBlank(): String? = if (isNullOrBlank()) null else this
If we add another extension:
fun <R> String.whenNotNullOrBlank(block: (String)->R): R? = this.nullIfBlank()?.let(block)
This simplifies the code:
obj?.toString()?.whenNotNullOrBlank { doSomethingWith(it) }
You can always write extensions like this to improve the readability of your code.
Note. Sometimes I used a safe accessor ?. null and the other not. This is because the / lambdas predicate of some functions works with NULL values, while others do not. You can design them the way you want. This is for you!
For more information on this topic, see the Idiomatic Way to Solve Problems with nullables
Jayson minard
source share