Search code examples
kotlinnavigationandroid-jetpack-compose

How to send optional argument in jetpack compose navigation?


I'm trying to send optional arguments in jetpack compose navigation because if I don't send optional, this time it asks me for parameters every time I navigate to the screen, which makes the screens interconnected and causes problems.

I have a screen like this:

sealed class RegisterScreen(val route: String) {
 
   
    object ForgotPasswordScreen : RegisterScreen("forgot_password_screen")  
    object ForgotPasswordDetailScreen :RegisterScreen("forgot_password_detail_screen")
}

For example, I have a sealed class with classes like this and I want to give an optional boolean type parameter.

Hear is my Navigation graph:

fun NavGraphBuilder.registerLoginNavGraph(
    navHostController: NavHostController
) {

    navigation(
        startDestination = RegisterScreen.SignUpStartRegisterScreen .route,
        route = REGISTER_LOGIN_ROUTE
    ) {
       
        composable(RegisterScreen.ForgotPasswordScreen.route) {
            ForgotPasswordScreenRoute(navHostController)
        }
        composable(RegisterScreen.ForgotPasswordDetailScreen.route) {
            ForgotPasswordDetailScreen(navHostController)
        }
       
    }
}

I want to go to ForgotPasswordDetailScreen from ForgotPasswordScreen and I want to send an optional boolean type parameter to ForgotPasswordDetailScreen. How can I do this according to this structure? how do I adapt. I couldn't set things done on the internet to my own code, can you help me? It would be better if you explain with code


Solution

  • Adding optional arguments

    Optional arguments are defined following a query parameter syntax ("?argName={argName}") They must have a defaultValue set, or have nullable = true (which implicitly sets the default value to null) This means that all optional arguments must be explicitly added to the composable() function as a list:

    composable(
        "profile?userId={userId}",
        arguments = listOf(navArgument("userId") { defaultValue = "user1234" })
    ) { backStackEntry ->
        Profile(navController, backStackEntry.arguments?.getString("userId"))
    }
    

    Now, even if there is no argument passed to the destination, the defaultValue, "user1234", is used instead.

    The structure of handling the arguments through the routes means that your composables remain completely independent of Navigation and makes them much more testable.

    Keep in mind that a null value will be returned as a "null" string, so to actually check for presence, you will need to do something like:

    args.getString("userId")?.takeIf { it != "null" }