@Composable invocations can only happen from the context of a @Composable function - LazyColumn

125 views Asked by At

I am attempting to fetch a contact number and name, but I am encountering an error that states:

@Composable invocations can only happen from the context of a @Composable function.

how to resolve this issue?

data class Contact(val name: String, val phoneNumber: String)

@Composable
fun ContactList(){
    val context = LocalContext.current
    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted, fetch the contacts
            val contacts = fetchContacts(context)
            LazyColumn {
                items(contacts) { contact ->
                    Text(text = "Name: ${contact.name}, Phone: ${contact.phoneNumber}")
                    Spacer(modifier = Modifier.padding(10.dp))
                }
            }
        } else {
            // Handle the case when the user denies the permission
        }
    }

    // Request permission to read contacts
    launcher.launch(Manifest.permission.READ_CONTACTS)
}

private fun fetchContacts(context: Context): List<Contact> {
    val contacts = mutableListOf<Contact>()
    val cursor = context.contentResolver.query(
        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
        null,
        null,
        null,
        null
    )

    cursor?.use {
        while (it.moveToNext()) {
            val name = it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
            val phoneNumber = it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
            contacts.add(Contact(name, phoneNumber))
        }
    }

    return contacts
}
1

There are 1 answers

0
HexedAgain On

rememberLauncherForActivityResult(...) takes a second parameter onResult which is just a standard callback (not a composable one). You are getting the error as you are trying to call a composable function (LazyList { ... }) where a normal one was expected. The way I'd handle this situation is to change some state variable either locally, or in the viewmodel, when onResult fires - and then listen to changes to this variable in the UI where you will then display the lazy list