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?
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.