raamcosta / compose-destinations

Annotation processing library for type-safe Jetpack Compose navigation with no boilerplate.
https://composedestinations.rafaelcosta.xyz
Apache License 2.0
3.15k stars 132 forks source link

Navigation destination that matches request NavDeepLinkRequest cannot be found in the navigation graph when using both app-level graph and module graphs #150

Closed Nek-12 closed 2 years ago

Nek-12 commented 2 years ago

Hi, I'm not sure if this is a bug or just me not being able to properly setup my navigation graphs. I have a multi-module project currently in the state of being partially modularized. This means I have 80% of my destinations in the app module and some in feature modules. I'm using compose-destinations.mode=destinations, and I gather them in the following nav graph:

object NavGraphs {

    val root = object : NavGraphSpec {
        override val destinationsByRoute
            get() = buildList {
                addAll(destinations) //destinations variable generated in the app module
                add(DashboardScreenDestination) //feature-module destination
            }.routedIn(this).associateBy { it.route }

        override val route: String = "root"

        override val startRoute get() = HomeScreenDestination routedIn this //one of the app-level destinations
    }
}

For now I only want to have a root nav graph, and I add to it all the feature destinations. However, when trying to navigate to any of the screens, I now get

Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/edit_ritual_screen?ritualId=0 } cannot be found in the navigation graph NavGraph(0x78dcd1ef) route=root startDestination={Destination(0xe2c1fac) route=root/home_screen}

The android-app://blah deeplink look very suspicious to me. I suppose I haven't added my destinations to a nav graph properly. I'm using Navgraphs.root when calling DestinationsNavHost. What's most puzzling is that the start destination opens just fine. (the app does not crash on start)

What can I do about this?

raamcosta commented 2 years ago

Hi @Nek-12 :)

I suppose you took the routedIn from the tivi fork project. That is the problem. If you open routedIn documentation it says it returns DynamicDestinationSpec and if you read that (yeah I guess I could also add this to the routedIn method docs) it says:

"DestinationSpec created by routedIn / withDeepLink methods. These are useful if you have annotated Composable used on multiple NavGraphSpecs. For all intents and purposes, it will be an entirely different destination, except that it will have the same navigation arguments and call the same Composable, when it gets navigated to. To navigate to a DynamicDestinationSpec you need to use within, for example: navigator.navigate(YourScreenDestination(yourNavArgs) within YourNavGraph) Note that the YourNavGraph in the above example MUST match the one used when NavGraphSpec is defined with routedIn, otherwise the resulting DynamicDestinationSpec will not exist in the navigation graph and it will crash at runtime."

So, this is only useful if you have destinations that must belong to the multiple navigation graphs. It basically creates a copy of the original changing the route (so it doesn't clash with others from other nav graphs) adding as prefix the route of the nav graph you pass in.

Sorry for the longwinded answer.

TL;DR: Remove routedIn calls and all will work 😉 Or, of course, use within NavGraphs.root when you want to navigate to them. But most likely, you won't need that.

Nek-12 commented 2 years ago

Yes, thank you for the answer. Yes, I did not read the documentation, my bad :( I actually solved the issue by indirectly removing the routedIn call while I was migrating to the "navgraphs" approach (and generated a navgraph for my app module) I wish the documentation in the multimodule section was a little more verbose. The examples aren't very explanatory to me. Thank you again for the answer.

raamcosta commented 2 years ago

I wish the documentation in the multimodule section was a little more verbose. The examples aren't very explanatory to me.

Totaly. I have been meaning to make a proper section in documentation website about multi module setups but I haven't had time to. The plan atm is stopping or slowing down with features so I can focus on documentation. Hopefully I get it done soon!

Thanks for the feedback and for opening this instead of giving up on the library 🙏 Hope it helps you!