How can I pass a String parameter to a ViewModel i...
# compose
p
How can I pass a String parameter to a ViewModel in Compose? In the codelabs they explain how to pass parameters than can be generated using Application, like this:
Copy code
companion object {
        val factory : ViewModelProvider.Factory = viewModelFactory {
            initializer {
                MyViewModel(
                    MyApplication().container.repository
                )
            }
        }
    }
And later using that companion object variable like this:
Copy code
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?
m
Is the string hardcoded or does it come from somewhere? And what navigation library are you using? The answer will probably depend on that
p
No navigation library, is a very simple app with a screen and a viewmodel, it's for learning purposes, and I just need to pass a string to the viewmodel, that string is not hardcoded.
Doesn't exist a simple way of passing a variable of type string to a viewmodel as a parameter?
m
Yes you can like this I think
Copy code
@Composable
fun MyScreen(
    param: String,
    viewModel: MyViewModel = viewModel {
        MyViewModel (
            param = param,
            repo =  MyApplication().container.repository,
        )
    },
)
Some of the navigation libraries handle it for you by making navigation arguments available via the
SavedStateHandle
in the VM.
You don't need the factory companion object in this case
p
are you sure that it is that easy? then why in every codelab I did in the last months they use factory for passing parameters for viewmodel? even before compose just in kotlin and views they did that way.
I think we are lossing something if we dont use factory, maybe something is broken in a configuration change or recomposition
are you sure is not necessary?
p
You can modify your ViewModel to receive the String in a start() function rather than the constructor. Then call this function from the lifecycle::onStart(param) passing the desired data. Or use koin, koin allows partial injection or
assisted injection
as it is known too.
p
the point is that I'm trying to do it without using third party libraries, just wanna learn how to pass a simple variable using a factory, a companion object and a viewmodel, just that
maybe is not possible?¿
I'm lossing all the day with this, and until now, no one can help with it without using third party libraries, can't believe it
p
Yeah I don't think the
viewModel { factory = MyFactoryGlobalReference }
function was created with assisted injection in mind. I believe that if you are using the compose navigation library, and SavedStateHandle in your ViewModel(savedStateHandle). The ViewModel will receive the arguments from the navigation in the savedStateHandle. But I haven't used that so I can't provide much details.
181 Views