Merry X-Mass Everyone,
I am trying to navigate from the first screen to a second screen and I need to provide an integer identifier to load stuff from API on the second screen.
I'm running into this error when trying to pass an Int Nav Argument.
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
This is my NavHost where I use /{recipeId} as my placeholder on the 2nd Screen's route.
NavHost(
navController = navController,
startDestination = Screens.RecipesOverviewScreen.route
) {
//1st Screen
composable(route = Screens.RecipesOverviewScreen.route) {
RecipesOverviewScreen(
navController = navController,
onToggleTheme = { app.toggleLightTheme() })
}
//2nd Screen
composable(route = "${Screens.RecipeDetailScreen.route}/{recipeId}")
{
RecipeDetailScreen()
}
I then call navController.navigate() in the first screen passing in an id of type Int into the navigation route.
RecipeList(recipes = listState.recipes,
onClickRecipeCard = { id ->
//insert corresponding Int id into the Nav route
navController.navigate(
route = "${Screens.RecipeDetailScreen.route}/${id}"
)
}
Inside the 2nd Screen's ViewModel I retrieve the nav argument using the SavedHandleInstance.
@HiltViewModel
class RecipeViewModel @Inject constructor(
savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
//pass in the key inside get() fxn
savedStateHandle.get<Int>(Constants.PARAM_RECIPE_ID)
?.let { id ->
//perform an API call inside init{} using nav arg id
getRecipe(id = id, token = token)
} ....}
At this point, the app is crashing and I am getting the above logcat output.
Kindly point me in the right direction on passing an Int Nav arg.
CodePudding user response:
When you defined your 2nd screen as:
composable(route = "${Screens.RecipeDetailScreen.route}/{recipeId}") {
You didn't define any type for the recipeId argument. As per the Navigate with arguments guide:
By default, all arguments are parsed as strings. You can specify another type by using the
argumentsparameter to set atype
So if you want your recipeId to be an Int, you must declare it as an IntType:
composable(
route = "${Screens.RecipeDetailScreen.route}/{recipeId}",
arguments = listOf(navArgument("recipeId") { type = NavType.IntType })
) {
This will ensure that your call to savedStateHandle.get<Int> actually has an Int to find, rather than a String.
