Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Passing a suspend function wrapped in a lambda

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading