Search code examples
androidandroid-jetpack-composedagger-hilt

jetpack compose viewModel() is giving error "has no zero argument constructor" with hilt


In my project, compose viewModel() method is giving error "has no zero argument constructor" when I am using hilt.

@Composable
    fun HomeScreen(homeViewModel: HomeViewModel = viewModel()) {
    ...
    }
    
    @HiltViewModel
    class HomeViewModel @Inject constructor(private val repository: Repository) :
        ViewModel() {
    ...
    }
@Module
@InstallIn(ViewModelComponent::class)
abstract class DataModule {
    @Binds
    abstract fun bindRepository(
        fakePuppyRepository: RepositoryImpl
    ): Repository
}

these are my dependencies

implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'
    implementation 'androidx.activity:activity-compose:1.3.0-alpha03'
    implementation "androidx.navigation:navigation-compose:1.0.0-alpha08"
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
    implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-beta01'
    implementation "com.google.dagger:hilt-android:$hilt_version"
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
    kapt "com.google.dagger:hilt-compiler:$hilt_version"
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

Solution

  • Based on your dependencies, I suspect you are using NavController/NavHost.

    Add this dependency: androidx.hilt:hilt-navigation-compose:1.0.0-alpha01

    Now in your composable which defines NavController, call HomeScreen as follows:

    import androidx.compose.runtime.Composable
    import androidx.hilt.navigation.compose.hiltNavGraphViewModel
    import androidx.navigation.compose.NavHost
    import androidx.navigation.compose.composable
    import androidx.navigation.compose.rememberNavController
    
    ...
    
    @Composable
    fun Main() {
      val navController = rememberNavController()
      NavHost(navController, startDestination = "home"){
        composable("home") {
          val model: HomeViewModel = hiltNavGraphViewModel(it)
          HomeScreen(model)
        }
      }
    }
    
    ...
    

    hiltNavGraphViewModel(...) can also be replaced with viewModel(HiltViewModelFactory(LocalContext.current, backStackEntry)) (from https://github.com/google/dagger/issues/2166#issuecomment-769162910)