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
arguments
parameter 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
.