Navigating the obstacles of Navigation Compose
Published: 2023-09-08 16:41:46


## Introduction

Hello guys 👋👋, welcome back to another article, in our previous article
we
discussed [how to inspect network traffic using the Chucker dev extension in android](https://medium.com/@peterkagure/debug-and-inspect-your-network-requests-in-android-using-the-chucker-dev-extension-with-retrofit-or-2d7b82c51012).
In this article, I will show you a trick that can save you time when dealing with the nuisances of Navigation Compose

If you've used navigation compose, you may have noticed how sometimes it can
be a headache because it lacks compile time type safety, hence sometimes when
you navigate to a given route, your app crashes.This problem has led to the creation of 
type safe navigation libraries like compose destinations, voyager etc.
This can reduce your productivity as may spend time to debug the crash. 
Basically, to prevent the reoccurrence such crashes, we should abstract our 
navigation definitions through state hoisting. Don't understand what this 
means ....read on

Basically, state hoisting is practise in Jetpack Compose where we only expose
state and functions that modify the state to the composable.This results to
having 2 versions of one composable, Stateless and a stateful one.For more
information and the benefits of this practise,
read [this article](https://medium.com/@peterkagure/stateful-and-stateless-components-in-jetpack-compose-18f89f790750)
by me

## How we navigate In Jetpack Compose

Normally we navigate in compose by passing the navigation logic to the
onClick lambda where its needed as shown below

```
Button(
    modifier = Modifier.fillMaxWidth(),
    onClick = {
        navController.navigate(route="login")
    }
) {
      Text(text = "Login")
    
    }
```
The problem with this approach is that when if the NavHost where this navController
is defined does not have a route called "login", the app will crash. Normally if
you have one NavHost this won't be the issue since there is only one instance
of the navController(Unless you create a new one in your composable), but when
your app has a bottom Nav bar that requires its own NavHost, this approach can
become an issue since now you have multiple navControllers


## Solution
To solve this issue, we can define all necessary navigation definitions in 
our NavHost via explicit lambdas or extension functions to the NavController
class. This way we know what NavController has a route definition as shown below


```angular2html
val navController = rememberNavController()

NavHost(
    navController = navController,
    startDestination = Screens.DASHBOARD_SCREEN
    ) {
        composable(route = Screens.LOGIN_SCREEN) {
            LoginScreen(
                navigateToDashBoard = navController::navigateToDashBoard,
                navigateToSignUpScreen = navController::navigateToSignUpScreen,
            )

        }
        composable(route = Screens.SIGNUP_SCREEN) {
            SignUpScreen(
                navigateToLoginScreen = navController::navigateToLoginScreen,
            )
        }
        composable(route = Screens.DASHBOARD_SCREEN) {
            DashboardScreen(
                navigateToLoginScreen = navController::navigateToLoginScreen,
            )
        }
    }
```

This way we can pass the navigation functions to the composables without explictly 
having to define the navigation logic each time we need it. If we get the navigation
logic right top level, we won't need to worry about getting it right when actually 
navigating to the various screens.

Once again this won't help much if you have 1 NavHost you will see its benefits if
you have a bottom App Bar in your application 


I hope this tricks helps you build better apps using Jetpack compose.
Don't forget to clap for this article and leave a comment for any questions

While you are at it, you can follow my [GitHub](https://github.com/chege4179) 
profile to see some projects this in concept in practice