Search code examples
kotlinandroid-jetpack-composeandroid-jetpack-compose-material3

Kotlin Compose code multiple errors using Jetpack Compose and math


I am having multiple issues with a small section of code and can't determine why it doesn't work. I use the same structure throughout the code and have no other issues except here.

I have a composable that is doing math on a button press, and returning values based on those results.

My code is lengthy, and I have left out as much as I thought I could in order to provide necessary context of how things are working. This is my first Kotlin/Jetpack Compose project, and have been stuck on fixing this.

Here is what I have tried in the code:

ExposedDropdownMenuTax(
    taxVar,
    taxVarChanged = { newTaxVar ->
        taxVar = newTaxVar
    },
    options = options,
)
@OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun ExposedDropdownMenuTax(
        taxVar: String, taxVarChanged: (newTaxVar: String) -> Unit,
        options: List<String>,
    ) {
        var expanded by remember {
            mutableStateOf(false)
        }
        ExposedDropdownMenuBox(
            expanded = expanded,
            onExpandedChange = { expanded = !expanded },
            Modifier
                .padding(vertical = 8.dp)
                .width(180.dp)
        ) {
            TextField(
                readOnly = true,
                value = taxVar,
                onValueChange = { taxVarChanged(it) },
                label = { Text("Tax") },
                trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
                colors = ExposedDropdownMenuDefaults.textFieldColors(),
                modifier = Modifier.menuAnchor()
            )
            ExposedDropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false },
            ) {
                options.forEach { selectionOption ->
                    DropdownMenuItem(
                        text = { Text(text=selectionOption) },
                        onClick = {
                            taxVarChanged(selectionOption)
                            expanded = false
                        },
                        contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
                    )
                }
            }
        }
    }
ElevatedButtonSample(
    tankSize,
    onCalculationResult = { result ->
        totalFill = result.toString()
    },
    percent,
    onCalculationResult1 = { result ->
        gallonsLeft = result.toString()
    },
    manualGallons,
    onCalculationResult2 = { result ->
        amountFill = result.toString()
    },
    price,
    **taxVar,         // type mismatch inferred String but Double -> Unit expected
        onCalculationResult3 = { result -> // cannot infer type for result
    // Argument passed for onCalculationResult3
    totalCostWithTax = result.toString()
    }
) // No value passed for parameter "taxVar"**
@Composable
    fun ElevatedButtonSample(
        tankSize: String, onCalculationResult: (result: Double) -> Unit,
        percent: String, onCalculationResult1: (result: Double) -> Unit,
        manualGallons: String, onCalculationResult2: (result: Double) -> Unit,
        price: String, onCalculationResult3: (result: Double) -> Unit,
        taxVar: String,
    ) {
        var yesNo1 by rememberSaveable {
            mutableDoubleStateOf(0.0)
        }
        var yesNo2 by rememberSaveable {
            mutableDoubleStateOf(0.0)
        }
        var yesNo3 by rememberSaveable {
            mutableDoubleStateOf(0.0)
        }
        var yesNo4 by rememberSaveable {
            mutableDoubleStateOf(0.0)
        }
        var taxCalc by rememberSaveable {
            mutableDoubleStateOf(0.0)
        }
        ElevatedButton(
            onClick = {
                yesNo1 = if (tankSize.isNotEmpty()) {
                    try {
                        tankSize.toDouble()
                    } catch (e: Exception) {
                        0.0
                    }
                } else {
                    0.0
                }

                yesNo2 = if (percent.isNotEmpty()) {
                    try {
                        percent.toDouble()
                    } catch (e: Exception) {
                        0.0
                    }
                } else {
                    0.0
                }

                yesNo3 = if (manualGallons.isNotEmpty()) {
                    try {
                        manualGallons.toDouble()
                    } catch (e: Exception) {
                        0.0
                    }
                } else {
                    0.0
                }

                yesNo4 = if (price.isNotEmpty()) {
                    try {
                        price.toDouble()
                    } catch (e: Exception) {
                        0.0
                    }
                } else {
                    0.0
                }

                taxCalc = when(taxVar) {
                    "6% Sales Tax" -> 1.06
                    "4% Res. Tax" -> 1.04
                    else -> 1.00
                }

                onCalculationResult(yesNo1 * 0.8)
                onCalculationResult1(yesNo1 * (yesNo2 / 100))
                onCalculationResult2((yesNo1 * 0.8) - (yesNo1 * (yesNo2 / 100)))
                onCalculationResult3((((yesNo1 * 0.8) - (yesNo1 * (yesNo2 / 100))) * yesNo4) * taxCalc)
                // add if loop for Manual Gallons
            },
            modifier = Modifier.padding(horizontal = 45.dp)
        )
        { Text("Calculate") }
    }

Solution

  • You messed up the parameter order, you try to set taxVar for the parameter onCalculationResult3. The error message you get is a good indicator since it informs you that the type that you expect the parameter has (String) is different from what the compiler expects (Double -> Unit, a function).

    When calling a function you can explicitly name the parameters that you want to set. You already do this with some of the parameters, but not all. Especially the parameter in question, taxVar has no parameter name and so it is expected to be in the same order than in the function declaration, which it isn't.

    If you always provide parameter names (only do so if you put each parameter on a separate line) problems like this wouldn't even occur.