Search code examples
androidkotlinandroid-jetpack-composeandroid-viewmodelandroid-mvvm

How to pass a String parameter to a viewmodel in compose?


How can I pass a String parameter to a ViewModel in Compose? I mean a string variable, not a hardcoded one or an Application stored one. I need to pass it as a parameter. This is just for learning purposes, now it is a String but tomorrow can be a custom object for example.

In the codelabs they explain how to pass parameters than can be generated using Application, like this:

companion object {
        val factory : ViewModelProvider.Factory = viewModelFactory {
            initializer {
                MyViewModel(
                    MyApplication().container.repository
                )
            }
        }
    }

And later using that companion object variable like this:

viewModel: MyViewModel = viewModel(factory = MyViewModel.factory)

But they don't explain how to pass a simple String parameter. How can I adapt that code for receiving a String as a parameter and passing it when initializing the viewModel?

I tryed what CommonsWare sugested, and obviously it doesn't compile, something is missing in the explanation. How can I pass myString variable? I just wanna transform that factory to receive a String variable, but don't know how to achieve it.

companion object {
        val factory : ViewModelProvider.Factory = viewModelFactory {
            initializer {
                LoadingScreenViewModel(
                    myString
                )
            }
        }
    }

Solution

  • Option 1: Use a function

    companion object {
            fun factory(myString: String) : ViewModelProvider.Factory = viewModelFactory {
                initializer {
                    LoadingScreenViewModel(
                        myString
                    )
                }
            }
        }
    

    Option 2: Do not use a companion object, but instead initialize the factory at the point where you need it

            val myString: String = TODO() // fill in logic to get your string value
            val factory : ViewModelProvider.Factory = viewModelFactory {
                initializer {
                    LoadingScreenViewModel(
                        myString
                    )
                }
            }
    

    Option 3: Use your preferred dependency inversion framework (Dagger/Hilt, Koin, etc.) and avoid creating your own factory