-
-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to inject ViewModel in the screen? #28
Comments
Hi @5AbhishekSaxena ! 👋 So you have some options, I'll try to go over them.
@Composable
@Destination(start = true)
fun SampleScreen(
viewModel: SampleViewModel = hiltViewModel(),
navigator: DestinationsNavigator,
) {
// components
}
@Composable
fun NavigationComponent(
modifier: Modifier = Modifier
) {
DestinationsNavHost(
navGraph = NavGraphs.root,
modifier = modifier
) {
composable(SampleScreenDestination) {
SampleScreen(
viewModel = hiltViewModel(),
navigator = destinationsNavigator
)
}
}
} Btw number 2 can be used to pass anything that you may want to pass from the NavHost down (like lets say the Glad you opened this because it reminds me.. I should add a compile time error if you define some parameter that the lib cannot provide 🤔 Let me know if the solutions seem good to you! |
Ahh the compile-time error won't work because people can just be manually calling them. I can improve the error message though :) |
Thanks for the quick reply, I went with method #2 to avoid the default value thingy. If somebody isn't using hilt, they can refer to this @Composable
@Suppress("UNCHECKED_CAST")
private fun getSampleScreenViewModel(): SamplelScreenViewModel {
return viewModel(factory = object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return SampleScreenViewModel() as T
}
})
} and used it like this @Composable
fun SampleNavigationComponent(
modifier: Modifier = Modifier
) {
DestinationsNavHost(
navGraph = NavGraphs.root,
modifier = modifier
) {
composable(SampleScreenDestination) {
SampleScreen(
viewModel = getSampleScreenViewModel(),
navigator = destinationsNavigator
)
}
}
} Also, I found the documentation a bit confusing or missing details, would you mind if I suggest the changes? |
An IDE warning should work just fine. |
Not at all! I'd be thrilled if you could! 🙂 Btw if people are not using Hilt, your solution might not be enough if you plan to access the navigation arguments from the SavedStateHandle. For that you need something like this: class Factory(
navBackStackEntry: NavBackStackEntry
) : AbstractSavedStateViewModelFactory(
owner = navBackStackEntry,
defaultArgs = navBackStackEntry.arguments
) {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
return ProfileViewModel(handle) as T
}
}
// And to get the VM:
//...
val vm = viewModel<ProfileViewModel>(
factory = ProfileViewModel.Factory(navBackStackEntry)
) |
Cool, I'll create a PR with the suggestions for the documentation.
A really good solution, thanks. I'll update the same in my project. |
I'll close the issue then, feel free to reopen it or add more comments if you want to :) |
Hi
I was trying to use the library with the ViewModel with the screen. I usually inject the
ViewModel
into the screen via arguments as shown below.SampleScreen
When I try the same, I am getting a runtime error.
Could you please tell me if I missing some steps while setting up the library?
Navigation setup
How would you suggest injecting the VMs?
How would you use the library with the Hilt library?
The text was updated successfully, but these errors were encountered: