Search code examples
androidviewmodeldagger-hilt

how to pass custom args in hilt viewModel android


Screen(AppScreens.InfoScreen.route) { navBackStackEntry ->
    val viewModel = hiltViewModel<ProfileDisplayScreenViewModel>()
    val uiState by viewModel.uiState.collectAsState()
    LaunchedEffect(Unit) {
      viewModel.setUpId(navBackStackEntry.getInt()!!)
    }
    ProfileDisplayScreen(uiState, viewModel.interActor)
}

i don't want to use LaunchedEffect and i want to pass args directly is this possible ? if yes then how ?


Solution

  • Yes, you can pass arguments directly to your ViewModel without using LaunchedEffect. Here’s how you can achieve this using Hilt's SavedStateHandle and the Navigation Component.

    class ProfileDisplayScreenViewModel @ViewModelInject constructor(
          private val savedStateHandle: SavedStateHandle,
          // other dependencies
    ) : ViewModel() {
     val uiState = // Your state handling logic
    
        init {
            val id =
                savedStateHandle.get<Int>("id") ?: throw IllegalArgumentException("ID is required")
            setUpId(id)
        }
    
        fun setUpId(id: Int) {
             // Your logic to set up the ID
        }
    }
    

    When navigating to your screen, pass the argument like this:

    navController.navigate("info_screen/$id")
    

    Define the route in your NavHost to accept the argument.

    NavHost(navController, startDestination = "start_screen") {
    composable("info_screen/{id}")
    ) { navBackStackEntry ->
        val viewModel: ProfileDisplayScreenViewModel = hiltViewModel(navBackStackEntry)
        val uiState by viewModel.uiState.collectAsState()
        
        ProfileDisplayScreen(uiState, viewModel.interActor)
       }
    }