what is the correct way of replacing a route in co...
# compose
m
what is the correct way of replacing a route in compose navigation? Like:
Copy code
stack: [A, B, C] -> [A, B, D]
c
I use
popUpTo
for this. Something like
Copy code
navController.navigate("D") {
    popUpTo("C") { inclusive = true }
}
Not sure if there's a more idiomatic way.
You might be able to create an extension function
replaceWith(route: String)
that pops up to the current route.
m
that's the one I use too, but it looks (aesthetic) so hacky. Hmm, thanks, I'm gonna keep with it then
i
Yep, you are removing C, navigating to D, so that's exactly what you write.
s
Maybe mentally it makes more sense to you to replace “popUpTo(“C”)” with “popUpTo(“B”)“, so that it reads like: “Pop to B, and then navigate to D”. instead of “Pop up to C, and also get rid of C, and then navigate to D”. I wonder if these two are functionally equivalent in all cases btw. If it was me, I’d definitely write
popUpTo(B)
cause it’s the first thing that comes to mind when I want to achieve this.
i
In the simple case, where there aren't nested graphs involved,
popUpTo(B)
and
popUpTo(C) { inclusive = true }
would indeed always be the same
But if nested graphs are involved: say, A and B are top level destinations, but C and D are in a nested graph Y to provide a scope for shared ViewModels), then they would be different since the graphs themselves are also part of the same back stack, so the before back stack would be:
Copy code
A -> B -> Y -> C
If you
popUpTo(B)
, then you are also going to pop
Y
off the back stack and destroy its state, giving you a brand new copy that gets auto-inserted when you navigate to
D
(since
D
is part of Y's graph):
Copy code
A -> B -> Y' -> D
But if you
popUpTo(C) { inclusive = true }
, then
Y
will not be popped and will keep its state:
Copy code
A -> B -> Y -> D
But generally anything being done inside `Y`'s destinations would likely only reference other destinations only in Y (e.g., maybe that whole graph is your login graph provided by a separate module entirely), so you wouldn't really ever consider reaching up all the way to
B
in any case - you'd use
popUpTo(Y) { inclusive = true }
to pop the entire graph off the back stack no matter if you are on C or D, for instance
And that's precisely why the
inclusive
flag is there - because sometimes it makes more sense to say what you are popping up to but leaving behind and sometimes it makes more sense to say what exactly you are removing
s
Ah this makes a ton of sense! With all this context I think it makes a lot of sense not to do what I suggested above. Thanks a lot for this explanation!
m
that's a hell of a lesson, thanks