Reputation: 3567
I have this data class:
data class ReportItem(val label: String, val query: () -> Unit) {
override fun toString() = label
}
from which I want to create a list:
val reports = listOf(ReportItem(resources.getString(R.string.sales)) { RoomDB.getInstance(requireContext()).saleItems().getBySales() })
and I get this error:
Suspend function '@Query(...) suspend fun getBySales(): List' should be called only from a coroutine or another suspend function.
I know what that means, but I think that the error is wrong. After all, I'm not calling getBySales
at this point, I'm simply passing it along. Only when I call the query
function in ReportItem, getBySales
will actually be called (which, of course, happens inside a coroutine).
Is this a shortcoming of kotlin not being able to recognize that I'm not actually calling the suspend function? Or am I doing something wrong?
Upvotes: 4
Views: 255
Reputation: 37799
The idea is that you are calling getBySales
within the body of this lambda. So the compiler error should not be seen as something on the lambda as a whole but on this specific line within the lambda body. Just like you would see the same error if you called this same function from the body of a non-suspend function.
The reason why you get this error is that the type of the query
parameter of this constructor is not a suspend function - it's a regular function.
Just add the suspend
keywork on its type in the declaration:
data class ReportItem(val label: String, val query: suspend () -> Unit) {
override fun toString() = label
}
This will, in turn, force you to call query
only in suspending contexts, which is exactly what you want. This shouldn't be a problem for you because you mentioned you called it inside a coroutine.
Upvotes: 5