54

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
    

}

5 Answers 5

66

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
}
Sign up to request clarification or add additional context in comments.

8 Comments

Simply use inside compose exampleViewModel: ExampleViewModel = viewModel()
seems hiltViewModel() isn't available anymore
Following your setup I got the following error: CreationExtras must have a value by SAVED_STATE_REGISTRY_OWNER_KEY
Can you provide an example with @AssistedInject?
check this @desgraci medium.com/scalereal/…
|
13

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.

1 Comment

I added the dependency to my build.gradle, found that the version is up to 1.2.0 now as of 2/2024. Imported it in my Composable file, but It doesn't find hiltViewModel() Any suggestions?
11

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

  1. Adding androidx.hilt:hilt-navigation-compose dependency to your module level Gradle file. Do check for latest version(tested on 1.0.0-alpha03).
  2. @HiltViewModel to your ViewModel.
  3. @AndroidEntryPoint for the owner using the Composable function.

2 Comments

I am getting hiltViewModel() as an unresolved reference
@user16422658 me too, were you ever able to resolve?
6

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)

1 Comment

Thank you so much, I think scoping the view model to the nav graph is my best solution for now.
3

base document Inject Hilt In Composable Function

Note: notice to import class

Sample you can used viewModel()

Example:

...
import androidx.lifecycle.viewmodel.compose.viewModel
...
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) { /* ... */ }

Full Example:

...
import androidx.lifecycle.viewmodel.compose.viewModel
...
@HiltViewModel
class MyViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
    private val repository: ExampleRepository
) : ViewModel() { /* ... */ }

@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) { /* ... */ }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.