``` fun PeerMain(updatePage: ((value: PageType) -&...
# compose
c
Copy code
fun PeerMain(updatePage: ((value: PageType) -> Unit)) {
    Column(
        modifier = Modifier.padding(horizontal = 2.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        var scope = MainApplication.instance!!.coroutineScope;
        var accounts: List<Account>
        scope.launch {
            accounts = MainApplication.instance!!.db.account().getAll()
            if (accounts.isNotEmpty()) {
                accounts.forEach {
                    Text(it.address)
                }
            } else {
                Text(
                    "PeerMain"
                )
            }
        }
    }
}
how to correct this code?
c
accounts
need to be a state to have the text field updated it state. You can use
produceState
to call your suspend function. https://developer.android.com/develop/ui/compose/side-effects#producestate
I‘d encourage you to start at the beginning and understand how compose and state management works together https://developer.android.com/develop/ui/compose/state
c
I always get mind blown by android docs😑
Finally worked out!
Copy code
val accountList = remember { mutableStateOf<List<Account>>(ArrayList()) }
    LaunchedEffect(Unit) {
        val scope = MainApplication.instance!!.coroutineScope
        scope.launch {
            accountList.value = MainApplication.instance!!.db.account().getAll()
        }
    }

    // If the list is empty, it means that our coroutine has not completed yet and we just want
    // to show our loading component and nothing else. So we return early.
    if (accountList.value.isEmpty()) {
        Text("No Peer Found!")
        return
    } else {
        accountList.value.forEach {
            Text(it.address)
        }
    }
c
If you use
produceState
your code will be more readable. Also you do not need a
scope
, the LaunchedEffect is started in a coroutine scope.
c
produceState doesn't have understandable code snippets for reference.
line 181
c
Copy code
val accountList = produceState(emptyList()) {
            value = MainApplication.instance!!.db.account().getAll()
        }
c
Copy code
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
c
getAll() is a
suspend
function, right?
c
yes.
Copy code
val accountList = remember { mutableStateOf<List<Account>>(ArrayList()) }
    LaunchedEffect(Unit) {
        val scope = MainApplication.instance!!.coroutineScope
        scope.launch {
            accountList.value = MainApplication.instance!!.db.account().getAll()
        }
    }
this snippet works.
c
and what database framework do you use? there is a big issue with your suspend function. they should, by definition, be main-safe. anyway, wrap the suspend function call in a
withContext
to switch away from the main thread:
Copy code
val accountList =
            produceState(emptyList<String>()) {
                value =
                    withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
                        MainApplication.instance!!
                            .db
                            .account()
                            .getAll()
                    }
            }
c
the scope is Dispatchers.IO coroutine.
c
yes, but you don’t need a new scope you only need a new context. 😉
c
✌️*, will look into it later.*
👍🏼 1