I'm struggling a bit to understand Higher-Order Functions and how to pass functions as parameters to other functions using Kotlin. I have a basic example that I want to fufill:
fun addOnSearchGameResultListener(
activity: AppCompatActivity,
releaseThread: () -> Unit,
showNoResultsFoundMessage: () -> Unit,
updateSearchResults: (result: List<Game>) -> Unit) {
var event0017Handler: TaskExecutor = object : TaskExecutor {
override fun executeOnSuccessTask(response: JSONObject) {
async() {
uiThread {
try {
releaseThread()
mLoaderManager.hideIndeterminateProgressBar(activity)
val result = mJSONParser.getGamesByGameKey(response)
Log.i(GameController::class.simpleName, "response: ${result.toString()}")
updateSearchResults(result)
} catch (e: JSONException) {
showNoResultsFoundMessage()
}
}
}
}
override fun executeOnErrorTask(payload: JSONObject) {
releaseThread()
mNotificationManager.showErrorPopUp(activity, payload.getString("data"))
}
}
NotificationCenter.RegistrationCenter.registerForEvent(EventCatalog.e0017, event0017Handler)
}
I'm calling the method above this way:
mGameService.addOnSearchGameResultListener(
this,
releaseThread(),
showNoResultsFoundMessage(),
updateSearchResults(null)
)
And updateSearchResults(null)
is declared as:
private fun updateSearchResults (results : List<Game>?) : (results : List<Game>?) -> Unit = {
if (null != results && results.size > 0) {
mLastMatchingQuery = query_container.text.toString()
hideNoResultsFoundMessage()
mGames = results
mAdapter!!.dataSet = results.toMutableList()
} else {
showNoResultsFoundMessage()
}
}
I know I passed null to the func when I declared it ('cause I need to pass something at compilation time), however, the call made from inside addOnSearchGameResultListener()
is not made passing the parameter from runtime, I mean, in addOnSearchGameResultListener()
I always get null for results. How exactly this works and what am I doing wrong?
In Javascript, functions can be assigned to variables in the same way that strings or arrays can. They can be passed into other functions as parameters or returned from them as well. A “higher-order function” is a function that accepts functions as parameters and/or returns a function.
Benefits of higher-order functionsThey are an excellent way to abstract and separate actions in a program. They are easy to reuse. They provide simplicity to the code, allowing the programmer and any other party to understand the code at a high level easily.
A lambda expression is a shorter way of describing a function. It doesn't need a name or a return statement. You can store lambda expressions in a variable and execute them as regular functions. They can also be passed as parameters to other functions or be the return value.
?: takes the right-hand value if the left-hand value is null (the elvis operator). :: creates a member reference or a class reference.
I think the confusion comes from parameter names, results
in particular. To resolve that you can change the updateSearchResults
to i.e.:
private fun updateSearchResults() : (List<Game>?) -> Unit = { results ->
if (null != results && results.size > 0) {
mLastMatchingQuery = query_container.text.toString()
hideNoResultsFoundMessage()
mGames = results
mAdapter!!.dataSet = results.toMutableList()
} else {
showNoResultsFoundMessage()
}
}
However I do feel that it would easier to follow the code if you'd apply following changes:
make updateSearchResults
regular method:
private fun updateSearchResults (results : List<Game>?) {
if (null != results && results.size > 0) {
mLastMatchingQuery = query_container.text.toString()
hideNoResultsFoundMessage()
mGames = results
mAdapter!!.dataSet = results.toMutableList()
} else {
showNoResultsFoundMessage()
}
}
change the addOnSearchGameResultListener
invocation and pass a lambda
mGameService.addOnSearchGameResultListener(
this,
releaseThread(),
showNoResultsFoundMessage(),
{ updateSearchResults(it) }
)
apply similar changes to releaseThread
, showNoResultsFoundMessage
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With