Issue description:
When I try to create custom navigation type and navigate to certain destination in my NavGraph, I get error, which states, that this certain destination cannot be found in the graph. After checking, some of items on list of adressess have street name for example Green Street 1 which doesn't cause any issue, but adressess with street name as Green Street 1/3 do. I suppose it might be related to the androidx.navigation library itself, as under the hood, navigation in this library works with URLS, which contain slashes between variables.
Actual outcome:
Application crashes after navigating to address with slash "/" sign
Expected outcome:
Application doesn't crash after navigation to adressess both with and without "/" sign in it.
Code:
@Serializable
data class Address(
val city: String?,
val companyId: Int,
val country: String?,
val gpsCoordinates: String?,
val id: Int,
val pointName: String? = null,
val pointType: String,
val postalCode: String?,
val street: String?
)
val AddressType = object : NavType<Address?>(isNullableAllowed = true) {
override fun get(bundle: Bundle, key: String): Address? {
return bundle.getString(key)?.takeIf { it != "null" }
?.let { Json.decodeFromString<Address>(it) }
}
override fun parseValue(value: String): Address? {
return if (value == "null") null else Json.decodeFromString<Address>(value)
}
override fun serializeAsValue(value: Address?): String {
return Json.encodeToString(value)
}
override fun put(bundle: Bundle, key: String, value: Address?) {
bundle.putString(key, Json.encodeToString(value))
}
}
In my NavGraph everything looks correct, as I am able to navigate to destinations without street name containing "/" sign.
Thanks @ianhanniballake
If someone would look for a solution to this issue for Compose Multiplatform:
@OptIn(ExperimentalEncodingApi::class)
val AddressType = object : NavType<Address?>(isNullableAllowed = true) {
override fun get(bundle: Bundle, key: String): Address? {
return bundle.getString(key)?.takeIf { it != "null" }
?.let { Json.decodeFromString(Base64.UrlSafe.decode(it).decodeToString()) }
}
override fun parseValue(value: String): Address? {
return if (value == "null") null else Json.decodeFromString(Base64.UrlSafe.decode(value).decodeToString())
}
override fun serializeAsValue(value: Address?): String {
return Base64.UrlSafe.encode(Json.encodeToString(value).encodeToByteArray())
}
override fun put(bundle: Bundle, key: String, value: Address?) {
bundle.putString(key, Base64.UrlSafe.encode(Json.encodeToString(value).encodeToByteArray()))
}
}