skip to content
Law

Migrating to type-safe navigation

/ 1 min read

Table of Contents

In case I forget, this is how I migrated to Compose’s type-safe navigation.

import kotlinx.serialization.Serializable
@Serializable
object Job

And then inside the NavHost

composable<Job> {
JobNavigation(
jobViewModel = jobViewModel,
navHostController,
)
}

Passing a value

Currently, when opening the job details page, I need to pass an integer ID.

bottomNavHostController.navigate("${JobAppRoutes.JOBDETAILS_ROUTE}/${jobData.id}")

Right now inside my NavHost

composable(
route = "${JobAppRoutes.JOBDETAILS_ROUTE}/{${JobAppRoutes.JOBDETAILS_ID}}",
arguments =
listOf(
navArgument(JobAppRoutes.JOBDETAILS_ID) {
type = NavType.IntType
},
),
) { navBackStackEntry ->
val arguments = requireNotNull(navBackStackEntry.arguments)
val jobData =
jobViewModel.jobList.filter {
it.id == arguments.getInt(JobAppRoutes.JOBDETAILS_ID)
}
}

So much going on.

Let’s migrate this to type-safe.

import kotlinx.serialization.Serializable
@Serializable
data class JobDetail(val id: Int)

Replace our code block inside our NavHost

composable<JobDetail> { backStackEntry ->
val jobDetail: JobDetail = backStackEntry.toRoute()
val jobDetailId = jobDetail.id
}

And lastly, replace our navigate call.

val jobDetail = JobDetail(id = jobData.id)
bottomNavHostController.navigate(jobDetail)