Home > Software design >  Cast Error on passing Integer Nav Argument using SavedStateHandle in Compose
Cast Error on passing Integer Nav Argument using SavedStateHandle in Compose

Time:12-26

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 a type

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.

  • Related