Home > Net >  ViewModel isActive stills true after route change in Jetpack Compose
ViewModel isActive stills true after route change in Jetpack Compose

Time:01-24

I have an app that has a bottom nav , it has some tabs, now, from tab A I have a ticker that updates a value in the view every 5 seconds, when I switch to tab B I'm expecting that the scope of the viewmodel that is associated with the route A is no longer active to keep executing the code, alltought I expect the viewmodel to survive since there is no sense of removing it on tab change.

My current code

NavGraph

 NavHost(navController, startDestination = BottomNavItem.HomeScreen.screen_route) {
        composable(BottomNavItem.HomeScreen.screen_route) {
            val homeViewModel: HomeViewModel = hiltViewModel()
            val homeUiState = homeViewModel.uiState.collectAsState()
            HomeScreen(uiState = homeUiState.value)
        }
        composable(BottomNavItem.FiatToCryptoScreen.screen_route) {
            val viewModel: CryptoToFiatViewModel = hiltViewModel()
            val uiState = viewModel.uiState.collectAsState()
            CryptoToFiatScreen(uiState = uiState.value)
        }
}

Now, HomeScreen takes HomeViewModel, which in the init block, it will fire a request every 5 seconds to get latest results from a coin

@HiltViewModel
class HomeViewModel @Inject constructor(private val repo: HomeRepository) : ViewModel() {

   init {
      updateFeaturedCoin()
   }

  private fun updateFeaturedCoin() {
        viewModelScope.launch {
            while (isActive) {
                val featuredCoinPrice = repo.getTickerForCoin("BTC")
                if (featuredCoinPrice.isSuccess) {
                    homeScreenState.update {
                        it.copy(
                            isLoading = false,
                            featuredCoinPrice = featuredCoinPrice.getOrNull()?.price
                        )
                    }
                }
                delay(5000)
            }
        }
    }

  ....
}

Now, this is working fine, my problem is that when I change tabs, lets say, going to CryptoTofiatScreen, and if I put a breakpoint in the isActive condition, this will never be false, and I need this cicle to stop executing if I move to another tab, because now the HomeViewModel is not in the foreground anymore to update its view.

How can I tell HomeViewModel that is not active anymore if I switch to another composable in the route ?

I tought that scoping the viewmodel to its route will trigger an event to tell the viewmodel is not active anymore if I change routes

CodePudding user response:

One option would be, to use a displosableEffect on the Home Composable, to start/stop viewmodel code:

DisposableEffect(Unit) {
    homeViewModel.setIsActive(true)
    onDispose {
        homeViewModel.setIsActive(false)
    }
}

This would require passing the viewModel instance to the component, instead of the just the state, like you are doing now.

  • Related