hi there! is there a better way to find if a desti...
# compose
o
hi there! is there a better way to find if a destination is in the backstack already, the idea behind this in 2 cases case1:
IntroScreen
can be the startDestination - which would later navigate to
DashboardScreen
and have a popUpTo to exclude it when closing case2:
DashboardScreen
is the startDestination - which can just open
IntroScreen
like any other as you see below, I want to either pop the stack if Dashboard already exists, or navigate to it and set popUpTo
Copy code
val launchApp: () -> Unit = {
    val found = try {
        navController.getBackStackEntry(Dashboard.route)
        true
    } catch (_: Exception) {
        false
    }

    if (found) {
        navController.popBackStack(route = Dashboard.route, inclusive = false)
    } else {
        navController.navigate(Dashboard.route) {
            popUpTo(Intro.route) {
                inclusive = true
            }
        }
    }
}
thoughts please, I feel like this is a hack
a
Navigation API doesn't want you to read the whole back stack for some reason. It feels like they consider it implementation detail. It's possible to get it (via currentBackStack or saveState) but it's clearly unwelcome use. And that navController.getBackStackEntry API is paternalistic: it does requireNotNull for you for no good reason so you have to do that ungodly try/catch. I ended up just having two nav graphs for similar use case (a conditional onboarding flow)
i
It sounds like this is an XY Problem: https://en.wikipedia.org/wiki/XY_problem What exactly are you trying to do?
We've talked about Login many, many times and there are never any cases where you should be using a login screen, tutorial screen, or anything like that as the start destination of your graph
You don't need to know anything about the current back stack to redirect a user to a login screen / tutorial if they haven't gone through that before
And looking at the back stack is never what you actually want to do when you consider deep links (where there isn't a back stack at all when a user deep links to a screen on the other apps back stack)
Here's just one of the previous threads on this, with a video that covers many of the reasons around the start destination and conditional navigation: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1617812338353700?thread_ts=1617805109.343700&cid=CJLTWPH7S
a
I think it's okay to answer this in the spirit of the theoretical feasibility of doing what they want, even if my immediate impulse is to question their priors as well. If they want to shoot themselves in the foot, we should advise on what gun to use. The reality is that UX navigation is heavily influenced by product requirements, and those requirements can differ a lot from what we perceive as good UX (Amazon's app multi-stack navigation comes to mind). Should we prohibit it at the API level? not sure.. I know it's all in good intentions (supporting deep links and restored states), but it sometimes seems unnecessarily restrictive. Especially that getBackStackEntry() throwing exception - that's just harsh đŸ™‚
i
That just means it isn't the right tool for what you're trying to do. So trying to figure out what you're trying to accomplish is absolutely the best place to start
a
I agree but it might sounds like going off topic to some people. With UX navigation it's hard to even define what constitutes navigation (e.g. is scrolling a navigation? some may say so)
o
thanks a lot guys, that video explains really well why the start destination should not be conditional and what to actually do, it makes sense, I made the necessary changes and looks much cleaner, although i would understand why someone would need to read the backstack if the code is too complex to do it correctly, in this case so much refactoring would be required, but that’s another problem thanks again!