I'm doing the same as shown in the documentation here. I want to Inject the ViewModel into a Composable function (Screen), but I get this error:
Cannot create an instance of class com.example.blotube.ui.later.LaterViewModel
My ViewModel:
@HiltViewModel
class LaterViewModel @Inject constructor(
private val database: Database
):ViewModel() {
val watchLater=database.videos().getAll()
}
My Composable Function (Screen):
@Composable
fun WatchLater(vm: LaterViewModel = viewModel()){
val videos=vm.watchLater.observeAsState()
val context= LocalContext.current
}
Inject ViewModel objects with HiltProvide a ViewModel by annotating it with @HiltViewModel and using the @Inject annotation in the ViewModel object's constructor. Note: To use Dagger's assisted injection with ViewModels, see the following Github issue.
If you use the Architecture Components ViewModel library, you can access a ViewModel from any composable by calling the viewModel() function.
There are two ways to declare the data within a ViewModel so that it is observable. One option is to use the Compose state mechanism which has been used extensively throughout this book. An alternative approach is to use the Jetpack LiveData component, a topic that will be covered later in this chapter.
We recommend screen-level composables use ViewModel instances for providing access to business logic and being the source of truth for their UI state. You should not pass ViewModel instances down to other composables.
From version androidx.hilt:hilt-navigation-compose:1.0.0-alpha02
you can inject view model into Composable functions by:
hiltViewModel<ViewModelType>()
Example:
@Composable
fun LoginScreen(viewModel: LoginViewModel) {}
LoginScreen(
viewModel = hiltViewModel<LoginViewModel>()
)
Android Developer Documentation compose and hilt
UPDATE:
import androidx.hilt.navigation.compose.hiltViewModel
@Composable
fun LoginScreen(
viewModel: LoginViewModel = hiltViewModel()
){
val videos=vm.watchLater.observeAsState()
val context= LocalContext.current
}
This appears to be a bug in Jetpack Compose, will probably need to wait for an update on the Jetpack libraries to address it.
As a possible workaround, you could instantiate the viewmodel in your activity and pass it to your composable function
val viewModel: LaterViewModel = viewModel(
"later_viewmodel",
factory = defaultViewModelProviderFactory
)
WatchLater(viewModel)
if you are using the Nav graph component you can also scope your viewmodel to the nav graph using
val viewModel: LaterViewModel = hiltNavGraphViewModel<LaterViewModel>()
WatchLater(viewModel)
You can use ViewModel directly inside Composable function via hiltViewModel()
@Composable
fun WatchLater(vm: LaterViewModel = hiltViewModel()) {
val videos = vm.watchLater.observeAsState()
val context = LocalContext.current
}
Please make sure to add following
I find the simplest way to do it is inside your composable function.
Add the dependency implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'
then;
@Composable
fun Foo(){
val viewModel : Bar = hiltViewModel()
}
then you can use the viewmodel as usual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With