Jetpack Compose – Suspend functions inside composables

When using suspend functions inside composables a common error is the following:

Suspend function should be called only from a coroutine or another suspend function

You can reproduce this error with a code like this:

suspend fun getData(): String {
    delay(1000L)
    return "Data"
}

@Composable
fun Screen() {
    val data = getData() // Suspend function 'getData' should be called...
    Text(data)
}

So, you need to call getData() inside the launch function of a coroutine. You can use rememberCoroutineScope for this

@Composable
fun Screen() {
    val scope = rememberCoroutineScope()

    scope.launch { // Calls to launch should happen inside a LaunchedEffect and not composition
        val data = getData() 
    }


    Text(data)
}

Now you will get the error Calls to launch should happen inside a LaunchedEffect and not composition, so let use the LaunchedEffect function

@Composable
fun Screen() {
    val scope = rememberCoroutineScope()

    LaunchedEffect(scope) {
        val data = getData()
    }

    Text(data)
}

Finally, you can save the variable data as a State variable in order that the screen recompose when data changes its value

@Preview
@Composable
fun Screen() {
    val scope = rememberCoroutineScope()
    val data = remember { mutableStateOf("")}
    LaunchedEffect(scope) {
        data.value = getData()
    }

    Text(data.value)
}

Leave a Reply

Your email address will not be published. Required fields are marked *