Skip to content

Commit 15f72c7

Browse files
authored
update: improve the web navigation examples (#419)
1 parent 7f731b2 commit 15f72c7

File tree

1 file changed

+58
-55
lines changed

1 file changed

+58
-55
lines changed

topics/compose/compose-navigation-routing.md

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ Here's an example of a simple type-safe navigation graph to use with the followi
140140

141141
@Composable
142142
internal fun App(
143-
navController: NavHostController = rememberNavController()
143+
onNavHostReady: suspend (NavController) -> Unit = {}
144144
) = AppTheme {
145-
145+
val navController = rememberNavController()
146146
NavHost(
147147
navController = navController,
148148
startDestination = StartScreen
@@ -167,6 +167,9 @@ internal fun App(
167167
composable<Id> {...}
168168
composable<Patient> {...}
169169
}
170+
LaunchedEffect(navController) {
171+
onNavHostReady(navController)
172+
}
170173
}
171174
```
172175
{default-state="collapsed" collapsible="true" collapsed-title="NavHost(navController = navController, startDestination = StartScreen)"}
@@ -182,40 +185,40 @@ In `wasmJsMain/kotlin/main.kt`, add the lambda to the `.bindToNavigation()` call
182185
fun main() {
183186
val body = document.body ?: return
184187
ComposeViewport(body) {
185-
val navController = rememberNavController()
186-
App(navController)
187-
LaunchedEffect(Unit) {
188-
window.bindToNavigation(navController) { entry ->
189-
val route = entry.destination.route.orEmpty()
190-
when {
191-
// Identifies the route using its serial descriptor
192-
route.startsWith(StartScreen.serializer().descriptor.serialName) -> {
193-
// Sets the corresponding URL fragment to "#start"
194-
// instead of "#org.example.app.StartScreen"
195-
//
196-
// This string must always start with the `#` character to keep
197-
// the processing at the front end
198-
"#start"
199-
}
200-
route.startsWith(Id.serializer().descriptor.serialName) -> {
201-
// Accesses the route arguments
202-
val args = entry.toRoute<Id>()
203-
204-
// Sets the corresponding URL fragment to "#find_id_222"
205-
// instead of "#org.example.app.ID%2F222"
206-
"#find_id_${args.id}"
207-
}
208-
route.startsWith(Patient.serializer().descriptor.serialName) -> {
209-
val args = entry.toRoute<Patient>()
210-
// Sets the corresponding URL fragment to "#patient_Jane%20Smith-Baker_33"
211-
// instead of "#org.company.app.Patient%2FJane%2520Smith-Baker%2F33"
212-
"#patient_${args.name}_${args.age}"
188+
App(
189+
onNavHostReady = { navController ->
190+
window.bindToNavigation(navController) { entry ->
191+
val route = entry.destination.route.orEmpty()
192+
when {
193+
// Identifies the route using its serial descriptor
194+
route.startsWith(StartScreen.serializer().descriptor.serialName) -> {
195+
// Sets the corresponding URL fragment to "#start"
196+
// instead of "#org.example.app.StartScreen"
197+
//
198+
// This string must always start with the `#` character to keep
199+
// the processing at the front end
200+
"#start"
201+
}
202+
route.startsWith(Id.serializer().descriptor.serialName) -> {
203+
// Accesses the route arguments
204+
val args = entry.toRoute<Id>()
205+
206+
// Sets the corresponding URL fragment to "#find_id_222"
207+
// instead of "#org.example.app.ID%2F222"
208+
"#find_id_${args.id}"
209+
}
210+
route.startsWith(Patient.serializer().descriptor.serialName) -> {
211+
val args = entry.toRoute<Patient>()
212+
// Sets the corresponding URL fragment to "#patient_Jane%20Smith-Baker_33"
213+
// instead of "#org.company.app.Patient%2FJane%2520Smith-Baker%2F33"
214+
"#patient_${args.name}_${args.age}"
215+
}
216+
// Doesn't set a URL fragment for all other routes
217+
else -> ""
213218
}
214-
// Doesn't set a URL fragment for all other routes
215-
else -> ""
216219
}
217220
}
218-
}
221+
)
219222
}
220223
}
221224
```
@@ -242,30 +245,30 @@ The code that does the matching needs to run before the `window.bindToNavigation
242245
fun main() {
243246
val body = document.body ?: return
244247
ComposeViewport(body) {
245-
val navController = rememberNavController()
246-
App(navController)
247-
LaunchedEffect(Unit) {
248-
// Accesses the fragment substring of the current URL
249-
val initRoute = window.location.hash.substringAfter('#', "")
250-
when {
251-
// Identifies the corresponding route and navigates to it
252-
initRoute.startsWith("start") -> {
253-
navController.navigate(StartScreen)
254-
}
255-
initRoute.startsWith("find_id") -> {
256-
// Parses the string to extract route parameters before navigating to it
257-
val id = initRoute.substringAfter("find_id_").toLong()
258-
navController.navigate(Id(id))
259-
}
260-
initRoute.startsWith("patient") -> {
261-
val name = initRoute.substringAfter("patient_").substringBefore("_")
262-
val id = initRoute.substringAfter("patient_").substringAfter("_").toLong()
263-
navController.navigate(Patient(name, id))
248+
App(
249+
onNavHostReady = { navController ->
250+
// Accesses the fragment substring of the current URL
251+
val initRoute = window.location.hash.substringAfter('#', "")
252+
when {
253+
// Identifies the corresponding route and navigates to it
254+
initRoute.startsWith("start") -> {
255+
navController.navigate(StartScreen)
256+
}
257+
initRoute.startsWith("find_id") -> {
258+
// Parses the string to extract route parameters before navigating to it
259+
val id = initRoute.substringAfter("find_id_").toLong()
260+
navController.navigate(Id(id))
261+
}
262+
initRoute.startsWith("patient") -> {
263+
val name = initRoute.substringAfter("patient_").substringBefore("_")
264+
val id = initRoute.substringAfter("patient_").substringAfter("_").toLong()
265+
navController.navigate(Patient(name, id))
266+
}
264267
}
268+
269+
window.bindToNavigation(navController) { ... }
265270
}
266-
267-
window.bindToNavigation(navController) { ... }
268-
}
271+
)
269272
}
270273
}
271274
```

0 commit comments

Comments
 (0)