I'm using compose-nav and currently have a destina...
# compose-android
c
I'm using compose-nav and currently have a destination defined as
Copy code
/dogdetails/{dogId}
but now I need to update it to take in a list/array of dogIds. It'll typically be 1 id, but can support 2+. I saw the docs talk about adding a list in another section of navigation, but it looks like all I'd need is NavType.IntArrayType, but I'm not sure how to create the string path. Do I just take my array and call tostring on it and compose nav knows how to handle it? Edit: Looks like no matter what I try to get IntArray working, I just keep getting a
java.lang.UnsupportedOperationException: Arrays don't support default values.
i
Did you see the Navigation 2.6.0-alpha01 release notes:
NavDeepLink
now supports default values for arrays, which allows support for repeated query params that will map to the argument's array type.
NavType
also now includes a default method which can be overridden to combine two parsed values. (Id68c3, b/209977108)
So you'd be able to write
/dogDetails?dogId={dogId}
and include multiple ids when you navigate e.g.,
dogDetails?dogId=47&dogId=74&dogId=12
c
Interesting... I'm not using this for deepLinks. but so it sounds like having a "path" arg be an array isn't possible? I need to make it an "arg" instead of a path?
e.g. this wont work?
Copy code
composable("dogs/{dogIds}",
              arguments = listOf(navArgument("dogIds") {
                defaultValue = intArrayOf(1)
                type = NavType.IntArrayType }))
          { DogPage(it.arguments?.getIntArray("dogIds")!!)

          }
i
You can certainly write your own
NavType
that parses the string
dogdetails/47_74_12
or
dogdetails/[47,74,12]
into an array, but you need to define what that parsing is
You can't just
toString
an array
c
Gotcha. The above "compiles" fine (i know that thats meaningless) but it does compile fine with " java.lang.UnsupportedOperationException: Arrays don't support default values." so maybe that just led me down the wrong path.
i
But if you use
dogDetails?dogId={dogId}
, you can certainly use
type = NavType.IntArrayType
directly
c
Gotcha. I guess I just misunderstood path navtypes vs arg nav types.
Tried updating to 2.6.0-beta01 and backQueue is now private? release notes dont mention a backup property to use. any tips on that?
FWIW (i didn't write this) but a previous team member wrote
Copy code
repeat(backQueue.size) { popBackStack() }
im assuming thats... not great? 🙈
i
That's never been a part of the public API surface (and that code actually pops way too many times, since backQueue also counts navigation graphs, not just screens). You'll want to popBackStack to the root graph's route
c
So just something like this would work fine?
Copy code
popBackStack(StartDestination.route, true)
oh. i misunderstood i think. you mean that navHost itself takes a route. very interesting. i think maybe i knew that?
i wonder if just using my start destination would work also
This call to navigate doesn't seem to work. The default value always gets populated instead. Am i missing something?
Copy code
val dogIdArray = intArrayOf(2)
HomeScreen(
    { navController.navigate("dogDetail?dogIds=$dogIdArray")
i
That's not what I said:
include multiple ids when you navigate e.g.,
dogDetails?dogId=47&dogId=74&dogId=12
You're still just `toString()`ing an array
c
Oh. I guess i completed whiffed this. So I just need to do
dogId=47&dogId=74&dogId=12
etc ?
i guess that makes sense. man. this ate up so much of my day. this whole stringly typed stuff just has a lot of foot guns. I honestly dont even know why NavType.IntArray even let me use it at all in 2.5.x. anyway. just venting because this soaked up my time. looking forward to type safe args 🤞
d
@Ian Lake Please correct me if I am wrong but: It’s not so bad if you consider the route to be a URL. If you know how a URL works then it makes what you can and can not do in the route far more clear.
152 Views