Thread
#compose
    YASAN

    YASAN

    11 months ago
    I am using Compose navigation for my app. I have 3 screens: A, B (dynamic) & C (dynamic). The user can navigate to a new C screen from all 3 screens but I want there to be only 1 C screen. so anytime a new version is navigated to, the old C should be removed from back stack. Can anyone help me how I can achieve that? I have tried a few things but none worked properly
    Note that B & C have dynamic routes which contains some id them. Any help would be great. I know it might be too simple but I couldnt figure it out 😕
    d

    darkmoon_uk

    11 months ago
    Apologies for not answering your question directly; but it may be helpful to consider not using Compose Navigation at all? I assume you're referring to the Jetpack Navigation integration with Compose. After some experience with different navigation mechanisms, it appears to me that Jetpack Navigation integration with Compose can be an unfortunate honeypot that leads people into thinking that's just 'how you do navigation' with Compose. It isn't so. I think all but the most complex cases can be served in the simplest way: by making the 'screen' that are you are just a high-level branch of the same
    @Compose
    -able declaration.
    Most of the time this approach elides much more nicely with Compose; the idea of an imperative back-stack kind of clashes with Compose's declarative philosophy. Jetpack Navigation has its use when retrofitting Compose to an existing project that's already heavily architected around the Stack concept, otherwise declarative feels simpler and more sustainable to me.
    To illustrate, your top level
    @Composable
    might include something like:
    val screen by myNavViewModel.screenFlow.collectAsState()
    when(screen) {
       Screen.A -> screenAContent(screenAViewModel)
       Screen.B -> screenAContent(screenBViewModel)
       ... etc.
    }
    ...perhaps all inside an
    AnimatedContent
    block to effect transition animations etc.
    It sounds like breaking free from Jetpack Navigation's back-stack can really address your use-case too: you're free to implement a stack of
    Screen
    if you want, or any other custom logic.
    YASAN

    YASAN

    11 months ago
    I understand what youre saying but it does not really answer my question 🤔 I know it can be achieved in other ways but I am pretty sure it should be possible with the compose navigation library since is a simple backstack pop.
    i

    Ian Lake

    11 months ago
    If you add
    popUpTo("c/${id}") { inclusive = true }
    to your
    navigate
    call then it'll pop everything between your current destination and the previous copy of C. That does nothing if C isn't on the stack at all, so it is safe to call every time you navigate to your new C
    It is a stack in every sense of the word though, so if you were A - > C -> B and then popUpTo C while navigating to C, you would get A -> C'
    YASAN

    YASAN

    11 months ago
    Thanks it works as I wanted! I actually had tried this before but my mistake was that I put actual variables inside the
    popUpTo
    route param and didnt put it like
    ${id}
    .
    i

    Ian Lake

    11 months ago
    It needs to match the
    route
    String exactly, character by character
    d

    darkmoon_uk

    11 months ago
    Can you ever have C, A, B on your stack? It sounds like that is possible from your description. If so, then would you need logic to re-push A and B?
    YASAN

    YASAN

    11 months ago
    Not really. C does not let the user to get to A/B unless you go back.
    I am not sure what you mean by repushing A and B really
    d

    darkmoon_uk

    11 months ago
    If C is always the last screen on the stack, then it sounds like you have your solution 👍 (That wasn't clear to me from description).
    i

    Ian Lake

    11 months ago
    Note that there's another flag,
    launchSingleTop
    that lets you specifically avoid multiple repeated copies of C on the top of the stack if you know there's never going to be anything on top of C
    So you get to choose if you want to pop everything back to C no matter where it is on the stack (global unique) or if you only care about repeats on the top (local unique)
    YASAN

    YASAN

    11 months ago
    My app is actually 5 pages and C is not always on top. but you can only get to C from A & B so I am pretty sure the backstack pop will work properly.
    I do always want a single instance of C but I dont want to reuse the old data if my C id is different
    i

    Ian Lake

    11 months ago
    Yep, sounds like
    popUpTo
    is exactly the right tool then
    Lucien Guimaraes

    Lucien Guimaraes

    11 months ago
    About compose navigation, I have a specific use case I'm also struggling with. Here is my use case: a bottomBar with 3 tabs, the last tab can display screen C (user not logged) or screen D (user logged). Screen C is a nested graph with all the login screens. In my HomeViewModel I expose if the user is logged or not and it's forwarded to the login nested graph (updating the startDestination) When user successfully signIn, I want to navigate to screen D and clearing the backstack, to avoid having login screens when user click on back button. How to do so properly?
    i

    Ian Lake

    11 months ago
    Lucien, I'd avoid co-opting someone else's thread and instead start your own for a completely different question, it'll make it a lot easier to track 🙂
    Lucien Guimaraes

    Lucien Guimaraes

    11 months ago
    Sorry, I will do it!