androidkotlinandroid-jetpack-composeandroid-viewmodelkotlin-multiplatform

Method in Kotlin Multiplatform ViewModel is not being called from Compose screen


I am working on a Kotlin Multiplatform (KMP) project, and I am facing an issue where a method in my ViewModel is not being called when I trigger it from a Compose screen. My ViewModel is located in the commonMain module and implements KoinComponent for dependency injection. However, when I try to call a method from the ViewModel in my Compose screen, it does not get executed, and no logs from the method appear.

Code in commonMain (RegistrationViewModel)

class RegistrationViewModel : CoroutineViewModel(), KoinComponent {

    fun signUp(request: SignUpRequest) {
        println("signUp method called with request: $request")
    }
}

Code in androidMain (RegistrationScreen):

@Composable
fun RegistrationScreen(
    onSignInClicked: () -> Unit,
    onRegisterButtonClicked: () -> Unit,
    navigateToMainScreen: () -> Unit
) {
    val viewModel = remember { RegistrationViewModel() }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        val loginValue = remember { mutableStateOf("") }
        val emailValue = remember { mutableStateOf("") }
        val passwordValue = remember { mutableStateOf("") }

        FPButton(text = "Sign In", onClick = {
            val signUpRequest = SignUpRequest(
                name = loginValue.value,
                emailAddress = emailValue.value,
                password = passwordValue.value
            )
            println("Button clicked, calling signUp()")
            viewModel.signUp(signUpRequest)
        })
    }
}

Problem: When I click the "Sign In" button, I see the log "Button clicked, calling signUp()", but the log from the signUp() method ("signUp method called with request: $request") never appears. This indicates that the method is not being executed.

What I have tried: Replacing remember { RegistrationViewModel() } with koinViewModel():

val viewModel: RegistrationViewModel = koinViewModel()

This did not resolve the issue.

Questions:

Why is the method signUp() not being called from the ViewModel?

Could this be related to the way ViewModel is created in commonMain in a KMP project?

Is there something wrong with using remember { RegistrationViewModel() } in a KMP context with Koin?


Solution

  • I solved the problem, and it wasn't related to creating the viewModel. In fact, for some reason, the print logs were not working in the commonMain module, even though there were no filters set for the logs.

    So, I implemented a function in the commonMain module:

    expect fun logMessage(tag: String, message: String)
    

    Then, I implemented the function in androidMain, and voilĂ , the logs appeared:

    actual fun logMessage(tag: String, message: String) {
        Log.d(tag, message)
    }