1

I checked out answers here and here to pass an Object from one composable to another and passing an @Serializable object as String from one composable to another but get the resulting error

  java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/detail/{"id":3,"email":"emma.wong@reqres.in","first_name":"Emma","last_name":"Wong","avatar":"https://reqres.in/img/faces/3-image.jpg"} } cannot be found in the navigation graph NavGraph(0x0) startDestination={Destination(0x60276fc4) route=start_destination}
        at androidx.navigation.NavController.navigate(NavController.kt:1530)

Data class

@Serializable
data class User (
    val id : Int,
    val email : String,
    val first_name : String,
    val last_name : String,
    val avatar : String
)

it's sample from reqres.in api, and NavHost to navigate between composables is

NavHost(
    navController = navController,
    startDestination = "start_destination",
    modifier = Modifier.padding(paddingValues)
) {
    composable(route = "start_destination") {
        ListScreen() { user ->
            val json: String = Json.encodeToString(user)
            navController.navigate("detail/$json")
        }
    }

    composable(route = "detail/{user}", arguments = listOf(
        navArgument("user") {
            type = NavType.StringType
        }
    )) { backStackEntry ->

        val arguments = requireNotNull(backStackEntry.arguments)
        val user = Json.decodeFromString<User>(string = arguments.getString("user")!!)
        DetailScreen(user = user)
    }
}

crash occurs when navController.navigate("detail/$json") is called.

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • Does this answer your question? [How pass parcelable argument with new version of compose navigation?](https://stackoverflow.com/questions/69059149/how-pass-parcelable-argument-with-new-version-of-compose-navigation). I know that you're trying to encode an object in a different way, but the answer is valid in both cases. – Phil Dukhov Sep 14 '21 at 11:15
  • @PhilipDukhov thanks for the suggestions but my question why parsing it causing an exception with the data encoded from an Object with kotlin serialize. I tried with another sample data class and it works fine. This is not the same question or another answer is required. I wonder the cause for navigation to not find the json string i provided – Thracian Sep 14 '21 at 11:19
  • Route is analog of a URL, and you can't just paste any string inside and expect it to be parsed. In your case I think that `{` and `}` are the symbols that navigation fails to parse clearly. You shouldn't work with compose navigation in this way, just pass object `id` and then read it from a repository. Check out [this answer](https://stackoverflow.com/a/69060224/3585796), it's made by Compose maintainer. – Phil Dukhov Sep 14 '21 at 11:24
  • I checked out the answer it suggests to expose every data source you have repository or ViewModel in my instance to NavHost, that's actually not i want and i'm not passing a Parcelable as stated as anti-pattern but passing it as String which only exposes the data itself to nav graph. And other answers that require using `currentBackStackEntry` are not straight forward and as mentioned in the comments are not working in same cases. Also passing a String is not working but as you suggested `Route is analog of a URL` so it might be not working due to data class itself containing a url for avatars – Thracian Sep 14 '21 at 11:48
  • Try encoding your string as described in [this answer](https://stackoverflow.com/a/68951045/3585796). – Phil Dukhov Sep 14 '21 at 11:52
  • 1
    After removing the avatar which contains`https://reqres.in/img/faces/3-image.jpg`, from data class it works fine, changed user.avatar with `URLEncoder.encode("http://alphaone.me/", StandardCharsets.UTF_8.toString())` it didn't work but it's apparent that source of problem is data class containing url. So if a data class contains url it's better to stay away from coding/decoding data class. – Thracian Sep 14 '21 at 12:12
  • 1
    @PhilipDukhov is actually right. It works just fine. All I had to do is just encode the url, update the data, convert it to json by using Gson and pass it with the route -> /data. – Junia Montana Oct 15 '21 at 18:19

0 Answers0