I am trying to inject navController
into my ViewModel -
ViewModel -
@HiltViewModel
class DeviceHolderListViewModelImpl @Inject constructor(
private val fetchUsersUseCase: FetchUsersUseCase,
private val navigationUtil: NavigationUtil
) : DeviceHolderListViewModel, ViewModel() {
// Trying to access navigationUtil here
}
NavigationUtil -
class NavigationUtil @Inject constructor(private val navController: NavController) {
fun navigateTo(destination: String, bundle: Bundle) {
when(destination) {
DEVICE_HOLDER_LIST -> navController.navigate(R.id.action_global_goto_deviceHolderListFragment, bundle)
DEVICE_HOLDER_DETAILS -> navController.navigate(R.id.action_global_goto_deviceHolderDetailsFragment, bundle)
}
}
fun navigateBack() {
navController.popBackStack()
}
}
NavigationModule -
@Module
@InstallIn(ActivityComponent::class)
object NavigationModule {
@Provides
fun provideNavController(activity: AppCompatActivity): NavController {
return Navigation.findNavController(activity, R.id.nav_host_fragment)
}
@Provides
fun provideNavigationUtil(navController: NavController): NavigationUtil {
return NavigationUtil(navController)
}
}
Upon trying to build the code, I get the following error -
error: [Dagger/MissingBinding] androidx.navigation.NavController cannot be provided without an @Inject constructor or an @Provides-annotated method.
IS it because I am trying to access the navController
from ViewModel
while it should be accessed from a Fragment or Activity?
My aim is to initiate navigation from the ViewModel. How do I ideally do that?
EDIT: Changes according to @DAA's answer -
NavigationUtil
class NavigationUtil {
private var navController: NavController? = null
fun setController(controller: NavController) {
navController = controller
}
fun clear() {
navController = null
}
fun navigateTo(destination: String, bundle: Bundle) {
when(destination) {
DEVICE_HOLDER_LIST -> navController?.navigate(R.id.action_global_goto_deviceHolderListFragment, bundle)
DEVICE_HOLDER_DETAILS -> navController?.navigate(R.id.action_global_goto_deviceHolderDetailsFragment, bundle)
}
}
fun navigateBack() {
navController?.popBackStack()
}
}
NavigationModule
@Module
@InstallIn(ActivityComponent::class)
object NavigationModule {
@Provides
@ViewModelScoped
fun provideNavigationUtil(): NavigationUtil {
return NavigationUtil()
}
}
NavigationUtil
class NavigationUtil {
private var navController: NavController? = null
fun setController(controller: NavController) {
navController = controller
}
fun clear() {
navController = null
}
fun navigateTo(destination: String, bundle: Bundle) {
when(destination) {
DEVICE_HOLDER_LIST -> navController?.navigate(R.id.action_global_goto_deviceHolderListFragment, bundle)
DEVICE_HOLDER_DETAILS -> navController?.navigate(R.id.action_global_goto_deviceHolderDetailsFragment, bundle)
}
}
fun navigateBack() {
navController?.popBackStack()
}
}