title: Jetpack Compose & Navigation: Problems share ViewModel in nested graph
body: <p>According to this <a href="https://developer.android.com/jetpack/compose/libraries#hilt-navigation" rel="noreferrer">example</a> I implemented shared viewModels in a nested navigation graph.</p>
  <h3>Setup</h3>
  <p><strong>Nested Graph:</strong></p>
  <pre class="lang-kotlin prettyprint-override"><code>private fun NavGraphBuilder.accountGraph(navController: NavHostController) {
     navigation(
        startDestination = &quot;main&quot;,
        route = &quot;account&quot;) {
  
         composable(&quot;main&quot;) {
            val vm = hiltViewModel&lt;AccountViewModel(navController.getBackStackEntry(&quot;account&quot;))
            //... ui ...
         }
  
         composable(&quot;login&quot;) {
            val vm = hiltViewModel&lt;AccountViewModel(navController.getBackStackEntry(&quot;account&quot;))
            //... ui ...
         }
     }
  }
  </code></pre>
  <p><strong>NavHost:</strong></p>
  <pre class="lang-kotlin prettyprint-override"><code>@Composable
  private fun NavHost(navController: NavHostController, modifier: Modifier = Modifier){
     NavHost(
        navController = navController,
        startDestination = MainScreen.Home.route,
        modifier = modifier
     ) {
        composable(&quot;home&quot;) { HomeScreen(hiltViewModel()) }
        composable(&quot;otherRoute&quot;) { OtherScreen(hiltViewModel()) }
        accountGraph(navController)
     }
  }
  </code></pre>
  <p><strong>BottomNavBar:</strong></p>
  <pre class="lang-kotlin prettyprint-override"><code>@Composable
  private fun ButtonNav(navController: NavHostController) {
     BottomNavigation {
        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentDestination = navBackStackEntry?.destination
  
        items.forEach { screen -&gt;
           BottomNavigationItem(
              icon = { ... },
              label = { ... },
              selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
              onClick = {
                 navController.navigate(screen.route) {
  
                    // Pop up to the start destination of the graph to
                    // avoid building up a large stack of destinations
                    // on the back stack as users select items
                    navController.graph.startDestinationRoute?.let { route -&gt;
                       popUpTo(route) { saveState = true }
                    }
  
                    // Avoid multiple copies of the same destination when
                    // re-selecting the same item
                    launchSingleTop = true
  
                    // Restore state when re-selecting a previously selected item
                    restoreState = true
                 }
              }
           )
        }
     }
  }
  </code></pre>
  <h3>Problem</h3>
  <p>With this setup if I naviagte to &quot;account&quot; (the nested graph) and back to any other route I get the error:</p>
  <pre class="lang-sh prettyprint-override"><code>java.lang.IllegalArgumentException: No destination with route account is on the NavController's back stack. The current destination is Destination(0x78dd8526) route=otherRoute
  </code></pre>
  <h3>Assumptions / Research Results</h3>
  <p><strong>BottomNavItem</strong></p>
  <p>The exception did not occure when I remove the <code>popUpTo(route)</code> onClick. But then I ended up with a large stack.</p>
  <p><strong>lifecycle of backStackEntry</strong></p>
  <p>Have a look at the following:</p>
  <pre class="lang-kotlin prettyprint-override"><code>//...
  composable(&quot;main&quot;) { backStackEntry -&gt;
     val vm = hiltViewModel&lt;AccountViewModel(navController.getBackStackEntry(&quot;account&quot;))
     //... ui ...
  }
  //...
  </code></pre>
  <p>I found out when navigating back the composable which will be left will be recomposed but in this case the backStackEntry seams to have another <code>lifecycle.currentState</code> because if I wrap the whole composable like this:</p>
  <pre><code>//...
  composable(&quot;main&quot;) { backStackEntry -&gt;
    if(backStackEntry.lifecycle.currentState == Lifecycle.State.RESUMED){
       val vm = hiltViewModel&lt;AccountViewModel(navController.getBackStackEntry(&quot;account&quot;))
       //... ui ...
    }
  }
  //...
  </code></pre>
  <p>... the exception did not occure.
  The idea with the lifecycle issue came into my mind when I saw that the offical example has <a href="https://github.com/android/compose-samples/blob/eafea81b85acc016454d815ceafe9a16cf566acc/Owl/app/src/main/java/com/example/owl/ui/NavGraph.kt#L122" rel="noreferrer">similar workarounds</a> in place.</p>
  <h3>Summary</h3>
  <p>I actually do not know if I did something wrong or if I miss a conecept here. I can put the lifecycle-check-workaround into place but is this really as intended? Additional to that I did not find any hint in the doc regarding that.</p>
  <p>Does anybody know how to fix that in a proper way?</p>
  <p>Regards,
  Chris</p>