Issue
Let's say I have the function
suspend fun doSomething(): Result {
val result = doStuff().await() //this is the suspending part
return result
}
I now want to build a generic function which can take functions like the one above as a parameter. Its main goal is to turn the passed result into a livedata object:
fun getResultLiveData(resource: Result): LiveData<Result> = liveData(Dispatchers.IO) {
emit(resource)
}
However, when I try calling the suspend function to get its result as a parameter, like so:
fun someLiveData = getResultLiveData(doSomething())
I get an (understandable) precompile exception for the part inside the brackets of getResultLiveData
:
Suspend function doSomething() should be called only from a coroutine or another suspend function
This obviously makes sense, but how do i annotate the parameter for my getResultLiveData as the result of a suspending function?
Now, if i were to do something like:
fun getResultLiveData(): LiveData<Result> = liveData(Dispatchers.IO) {
emit(doSomething())
}
It would work, because it is being called within the scope of a suspending part of the function (i.e. the LiveDataScope
). But I just want to go one abstraction step further...
Solution
As suggested by @CommonsWare, the solution is to pass a suspending function itself, and not the result of the function as a parameter. This also works when the suspending function has parameters.
The getResultLiveData
function should look the following:
fun getResultLiveData(resourceFunction: suspend () -> Result): LiveData<Result> = liveData(Dispatchers.IO) {
emit(resourceFunction())
}
And then you could easily call the function within a lambda expression:
getResultLiveData{doStuff(param1, param2)}
or simply
getResultLiveData{doStuff()}
Answered By - just_deko
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.