kotlinandroid-jetpack-composejetpack-compose-navigation

Navigation with Arguments with Jetpack Compose


I've been troubleshooting this issue for couple of days now about navigating with args in jetpack compose. I feel like I'm missing something simple, really simple that I can't figure out somehow. I tried making sure I'm coding it correctly but to no avail I still get the error.

So the error: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/second_screen/Item Six } cannot be found in the navigation graph NavGraph(0x0) startDestination={Destination(0x442b361f) route=home_screen}

I feel like I'm done everything correct but still cant get through this error. Or there is something simple that I'm missing.

My NavHost:

interface NavigationDestination{
    val route: String
}

@Composable
fun MainNavHost(
){
    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = HomeScreenNavigation.route,
    ){
        composable(HomeScreenNavigation.route){
            HomeScreen(onItemClick = {nameString->
                    navController.navigate("${SecondNavigationDestination.route}/${nameString}")
                        {
                            launchSingleTop = true
                        }
            })
        }
        composable(
            route = SecondNavigationDestination.routeWithArg,
            arguments = listOf(navArgument(SecondNavigationDestination.nameArg)
            {type = NavType.StringType})
        ){
            SecondScreen()
        }
    }
}

My Screens

First Screen:

object HomeScreenNavigation: NavigationDestination{
    override val route = "home_screen"
}

@Composable
fun HomeScreen(
    modifier: Modifier = Modifier,
    onItemClick: (String) -> Unit
){
    ItemList(
        itemList = LocalData.itemList,
        onItemClick = onItemClick
    )
}

@Composable
fun ItemList(
    itemList: List<ItemModel>,
    onItemClick: (String) -> Unit,
    modifier: Modifier = Modifier
){
    LazyColumn(
        verticalArrangement = Arrangement.spacedBy(9.dp)
    ){
        items(
            items = itemList,
            key = {it.id}
        ){
            Item(
                item = it,
                onItemClick = onItemClick
            )
        }
    }
}

@Composable
fun Item(
    item: ItemModel,
    modifier: Modifier = Modifier,
    onItemClick: (String) -> Unit
){
    Row(
        modifier = modifier
            .fillMaxWidth()
            .padding(9.dp)
            .clickable { onItemClick(item.name) },
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.Top
    ){
    Text(
        text = item.name
    )
    }
}

/////////////////////////////////////////////////////// Second Screen:

object SecondNavigationDestination: NavigationDestination{
    override val route = "second_screen"
    const val nameArg = "nameArg"
    val routeWithArg = "${route}/$nameArg"
}

@Composable
fun SecondScreen(
){
    val viewModel: MainViewModel = viewModel()
    Box(
    contentAlignment = Alignment.Center
    ){
        Text(
            viewModel.id
        )
    }
}

///////////////////////////////////////////////// ViewModel:

class MainViewModel(
    savedStateHandle: SavedStateHandle
): ViewModel(){
    val id: String = savedStateHandle[SecondNavigationDestination.nameArg] ?: "empty"
}

Solution

  • Change this

    val routeWithArg = "${route}/$nameArg"
    

    to this

    val routeWithArg = "${route}/{$nameArg}"
    

    For more info: docs