compose-destinations icon indicating copy to clipboard operation
compose-destinations copied to clipboard

ResultBackNavigator with multiple destinations (optionally with no result)

Open MaxMichel2 opened this issue 3 years ago • 7 comments

The idea would be to provide a list of destinations that the ResultBackNavigator should expect a result from.

I imagine something that would look like this:

// Implementation
ResultRecipient<listOf( // Destinations), Boolean>

// Interface
interface ResultRecipient<D : List<DestinationSpec<*>>, R> : OpenResultRecipient<R>

This would then allow us to have a onNavResult listener that passes both the result and the destination

Optionally, in some cases we actually just want to detect the navigateBack action without actually passing a result so this could also be an interesting and useful addition (Unless there is something that exists specifically for this that I'm unaware of)

MaxMichel2 avatar Nov 16 '22 10:11 MaxMichel2

Hi @MaxMichel2 👋

Navigating back with no result, absolutely there is already a method to do that!

The idea would be to provide a list of destinations that the ResultBackNavigator should expect a result from.

Do you mean the ResultRecipient?

If you're not sending a result, why are you using Result Back feature? 😄 If all you want is to be notified when you come back from a "forward" destination, you can just use the lifecycle from your NavBackStackEntry (which you can "ask" as a parameter of the annotated Destination) and whenever the ON_RESUME event is triggered you can probably do your stuff 😉

raamcosta avatar Nov 17 '22 22:11 raamcosta

Yes (Sorry for the delay) I mean the ResultRecipient 😄

In my case I'm not currently using the provided result but will likely use it in the future and all of my destinations will return a result of that type so I'd like to group them together since the importance isn't the destination but the result and with the current setup, we have to handle multiple different ResultRecipient variables (albeit, you can have a single listener for each but this still seems like duplicate code to me)

And yes, I thought of the ON_RESUME after posting this ^^ I've lost my XML reflexes with Compose ;)

MaxMichel2 avatar Nov 23 '22 10:11 MaxMichel2

I'll leave this as a possible enhancement for the future.

raamcosta avatar Dec 03 '22 13:12 raamcosta

Hi @raamcosta,

I have a similar situation where I need your help navigating from a fragment and sending the result back to another fragment that is not the previous one but another one on the stack.

My app has a flow of 4 screens that can be stacked on top of each other, namely A -> B -> C -> D. Each screen has a button "X" that cancels the entire flow and sends a result back. They also have another call to action that can finish the flow sending a result back.

However, when I call the setResult on the screen D, it sets the value on SavedStateHandle of the previous screen on the stack, which is screen C.

I was thinking of having a setResult function that also receives a Route/Destination, and then we could search the backstack for it. However, I'm concerned that the popBackStack to the origin will trigger the cancels in screens B and C.

fun setResult(route: Route, result : T)
    navController.getBackStackEntry(destinationRoute.route)?.savedStateHandle?.let {
        it[RESULT_BACK] = result
   ...
}

result.setResult(ADestination, result)

Can you provide some guidance on how to implement this navigation flow properly?

extmkv avatar Mar 21 '23 07:03 extmkv

Hi @extmkv

Sorry I didn't notice this question before.

There's no built-in support for something like that 🤔 You can probably find some custom solution, but I would need more time to get to whatever that would be 😅

raamcosta avatar May 13 '23 14:05 raamcosta

Maybe search for how to do this would normal compose navigation, that will definitely also work with compose destinations (maybe not as clean as with the result back feature though).

raamcosta avatar May 13 '23 14:05 raamcosta

Make Result back feature work between different modules....Please write the code from different module such as: ScreenA,ScreenB and ScreenC. ScreenB and ScreenC is different Module. I want to result back ScreenA but how it will be solved it? @destination() https://github.com/composable fun VendorProfileScreen( navBackStackEntry: NavBackStackEntry, resultRecipient: ResultRecipient<ScreenB, Boolean> // this line how to include ScreenC ) This is the scenario. @raamcosta

hozrotbelal avatar Oct 19 '23 12:10 hozrotbelal