There appear to be an infinite number of explanations for this error on stackoverflow, none of which address my issue.
I am building a compose alert dialog. I am trying to show a list of options that can change depending on the data.
@Composable
fun OptionSelectComposeDialog(
vm: OptionSelectDialogViewModel
){
...
val optionList = vm.optionList
Column {
if (openDialog.value) {
AlertDialog(
...
text = {
OptionListDialogContent(optionList)
},
...
)
}
}
In the OptionListDialogContent
composable function I'm trying to print out the list, but the Text
composable is giving an error.
OptionListDialogContent
@Composable
fun OptionListDialogContent(optionList: OptionList?) {
val optionItemArray = optionList?.getOptionItemArray(null)
LazyColumn() {
if (optionItemArray != null) {
optionItemArray.forEach { optionItem ->
Text(text = optionItem.toString()) // Error "@Composable invocations can only happen from the context of a @Composable function"
}
}
}
}
I suspected that the toString
call on the optionItem
is throwing this error, so I tried mapping the array to convert the array values to strings and still received this error.
OptionListDialogContent
After converting the array to strings:@Composable
fun OptionListDialogContent(optionList: OptionList?) {
val optionItemArray = optionList?.getOptionItemArray(null)
val optionItemStringArray = optionItemArray?.map { it.toString()}?.toTypedArray()
LazyColumn() {
if (optionItemStringArray != null) {
optionItemStringArray.forEach { optionItem ->
Timber.d("This is working? - optionItemArray.size: %s", optionItemArray.size)
Text(text = optionItem) // Error "@Composable invocations can only happen from the context of a @Composable function"
}
}
}
}
Anyone see where the issue is? (I have verified that optionItemArray
is not null)
Turns out it is an issue with how I was using LazyColumn. LazyColumn needs to receive an array size. There are different ways to do this, but this is how I did it:
LazyColumn() {
if (optionItemStringArray != null) {
items(optionItemStringArray.size) { i ->
Row() {
Text(text = optionItemStringArray[i])
}
}
}
}