Search code examples
kotlingetandroid-roomreturn-valuekotlin-coroutines

Get value from RoomDB into Composable function from Jetpack Compose


I have looked for many solutions but I found it as a newbie very complex on how to solve it properly without throwing away all my backend code.

I want to get an Float value from my RoomDB into a composable UI value but as far as we all know getting RoomDB values with queries needs an asynchronus scope. And those aren't capable of returning values because values stay within a scope and die there too. There is I think no way to no use Coroutine Scopes or anything else that doesn't block the UI loading so it can actually work.

What can I do? I don't want to throw away the entire RoomDB database neither our Jetpack Compose base GUI?

I tried replacing the 0.8f with a method that calls a Coroutine Scope which should idealistically return a Float value to this part of our code.

@Composable
fun ChargeScreen(){
    val context = LocalContext.current
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier.fillMaxSize()
    ){
        Column {
            ChargeTopText()
            CircularChargeBar(percentage = 0.8f, number =100 )
        }
    }
}


Solution

  • I am also new at Android Jetpack Compose but I can give you a suggestion for your case.

    Take a look at the code below

    @Composable
    fun YourComposable() {
        //Use remember for state management
        //Read more at https://developer.android.com/jetpack/compose/state
        var floatData by remember { mutableStateOf(0F) }
        var isLoading by remember { mutableStateOf(true) }
    
        //Side-effects
        //Read more at https://developer.android.com/jetpack/compose/side-effects
        LaunchedEffect(Unit) {
            isLoading = true
            floatData = getFloatDataFromDB()
            isLoading = false
        }
    
        //Just a way to show a progress indicator while we are getting the value from DB.
        if(!isLoading) {
            Text(text = "FloatData: $floatData")
        } else {
            CircularProgressIndicator(
                modifier = Modifier.size(50.dp),
                color = Color.Green,
                strokeWidth = 5.dp)
        }
    }
    
    suspend fun getFloatDataFromDB(): Float {
        //Using withContext(Dispatchers.IO) so it will execute in IO Thread.
        return withContext(Dispatchers.IO) {
            //Pretend this will take 5 seconds to complete
            Thread.sleep(5000)
            //And return the value
            return@withContext 0.9F
        }
    }
    

    I hope this will help you out!