'Jetpack compose - How to do popBackStack with arguments?

I have this scenario in which the user clicks on a button in composable A then selects an item from the list from composable B and selects another item from the list from composable C.

My problem is when I select an item from screen C I want to navigate back to screen A with whatever I selected in B & C. But popBackStack doesn't work when arguments are given.

Here is the code,

navController.popBackStack(route = Screen.SelectPlan.route + "?regionId=${region.id}&operatorId=${operator.id}")

Right now, I see that popBackStack does take a route argument, but converts it to a hashcode to navigate back instead of creating a Uri-like navigate function.



Solution 1:[1]

This is indeed a bug and it bothered me for a long time. After a long time of research and reading the navigation source code, I wrote my own extension function NavController.popBackStack to fix this problem. It is tricky but works for me. Also note that this version of extension function does not support the inclusive and saveState options (due to the current navigation API limitation), so you can't restoreState when you return to the current destination.

import android.content.Intent
import androidx.navigation.NavController

fun NavController.popBackStack(route: String): Boolean {
    if (backQueue.isEmpty()) {
        return false
    }

    var found = false
    var popCount = 0
    val iterator = backQueue.reversed().iterator()
    while (iterator.hasNext()) {
        val entry = iterator.next()
        popCount++
        val intent = entry
            .arguments
            ?.get("android-support-nav:controller:deepLinkIntent") as Intent?
        if (intent?.data?.toString() == "android-app://androidx.navigation/$route") {
            found = true
            break
        }
    }

    if (found) {
        navigate(route) {
            while (popCount-- > 0) {
                popBackStack()
            }
        }
    }
    return found
}

Solution 2:[2]

Try put "/" instead of ?

 navController.popBackStack(route = Screen.SelectPlan.route + "/regionId=${region.id}&operatorId=${operator.id}")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pfchen
Solution 2 Narek Hayrapetyan