How to deal with a route in `NavHost` that contain...
# compose
a
How to deal with a route in
NavHost
that contains polymorphic members … more in 🧵
Route:
Copy code
@Serializable
data class Detail(val model: DetailModel, val someFlags …)
Destination is defined as:
Copy code
fun NavController.navigateToDetail(model: DetailModel) {
    navigate(
        route = Detail(
            model = model,
            detailType = when (model) {
                is DetailModel.Detail1 -> …
                is DetailModel.Detail2 -> … // Make decision from combination of flag           
            },
        ),
    ) {
        popUpTo(Home) { inclusive = false }
    }
}
Since,
DetailModel
is a sealed class, I am getting the
Copy code
Route ….Detail could not find any NavType for argument model of type ….DetailModel - typeMap received was {}
After realising that the problem has something to do with
Polymorphism
, I used this guide to modify my
DetailModel
Now although the model looks alright, I am not sure why I am still getting this error and what I can do to resolve it.
This is the
DetailModel
in question
Copy code
@Immutable
@Serializable
sealed class DetailModel {
    abstract val name: String
    abstract val slug: String

    @Serializable
    @SerialName("detail1")
    data class Detail1(
        override val slug: String,
        override val name: String,
        val x …
    ) : DetailModel()

    @Serializable
    @SerialName("detail2")
    data class Detail2(
        override val name: String,
        override val slug: String,
        val y …
    ) : DetailModel()
}
Update: Found this https://kotlinlang.slack.com/archives/CJLTWPH7S/p1721173754215599?thread_ts=1721172672.676989&cid=CJLTWPH7S The Custom types section highlight on how to provide a
NavType
. I am still unsure on how to modify it for a sealed hierarchy case.
s
You can also treat the nav type as one big String, where you can turn your custom type entirely into 1 string using kotlinx.serialization and then turn it back from the string to the type again using serialization. With smth like this https://github.com/HedvigInsurance/android/blob/4889af954ac7a69ea181e73ddb5b9ba06b[…]om/hedvig/android/navigation/compose/JsonSerializableNavType.kt Then you can rely on kotlinx.serialization knowing how to (de/)serialize sealed interfaces by default if you mark the sealed interface itself as
@Serializable
along with all the instances https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes
a
Thanks for the pointer. I ended up doing
Copy code
typeOf<FindMyAgentListingModel>() to object : NavType<FindMyAgentListingModel>
for
typemap
and it works. Had to add
@Parcelize
on the sealed class. I may switch to the
string
decode/encode solution you mentioned as I find it nifty and neat.
s
Yup, this skips the parcelize part, as it stores it to the bundle as a string as well. But parcelize also works, you can pick whichever you prefer 😊
654 Views