Search code examples
androidkotlinandroid-jetpack-composeandroid-jetpack-navigation

Avoid API call in composable when navigating back to it


What I'm trying to do is avoid to make the api call that is called in a composable when press back from another composable.

I have composable DetailScreen that makes the api call and get some data and then navigate to composable EpisodeScreen, here is the thing, when I press back it's navigate back to composable DetailScreen but it makes de api call again and that is what I'm tryin to avoid.

Here is my Composable DetailScreen:

@Composable
fun DetailScreen(
    viewModel: DetailViewModel = hiltViewModel(),
    id: Int,
    name: String,
    picture: String,
    onClickBack: () -> Unit,
    onClickEpisode: (Int) -> Unit
) {

   
    LaunchedEffect(key1 = Unit) {
        //this is the line I'm trying to avoid when navigate back from composable EpisodeScreen
        viewModel.getCharacterDetail(id)
    }

...

Here is the navigation to composable EpisodeScreen:

private fun NavGraphBuilder.addDetailGraph(navController: NavHostController) {
    composable(
        route = Screen.Detail.route,
        arguments = listOf(
            navArgument("id") { type = NavType.IntType },
            navArgument("name") { type = NavType.StringType },
            navArgument("image") { type = NavType.StringType }
        )
    ) { backStackEntry ->
        val id = backStackEntry.arguments?.getInt("id") ?: 0
        val name = backStackEntry.arguments?.getString("name") ?: ""
        val image = backStackEntry.arguments?.getString("image") ?: ""

        DetailScreen(
            id = id,
            picture = image,
            name = name,
            onClickBack = {
                navController.popBackStack()
            },
            onClickEpisode = { episodeId ->
                navController.navigate(
                    Screen.Episode.createRoute(id = episodeId)
                ) 
            }
        )
    }
}

I tried to keep a state with remember and remembersaveable and put it as parameter in LaunchEffect() but nothing and I can´t find info or I can see it

Can anyone help me with this?? thanks in advance :)


Solution

  • Your DetailViewModel instance will still be alive when you navigate to the Episode screen, so you can put some logic there. You can do one of the following:

    • Create a boolean in your ViewModel, initially set to false. Inside the setCharacter function, check the value of this variable. If it's true just return otherwise change it to true and execute rest of the code. Or if you already have a variable in ViewModel which is initialized inside setCharacter, you can use that instead of that boolean.

    • Another option is to call in the setCharacter function inside the init block of the view model. And you can get the id from the SavedStateHandle that you can inject in the view model.