Jetpack Compose Navigation Return Result

December 17, 2021

Setup Jetpack Compose Navigation.

Return Result

@Composable
fun SelectPlaceScreen(viewModel: SelectPlaceViewModel = viewModel(), onBack: (Map<String, Any>?) -> Unit) {
    Button(onClick = {
        onBack(mapOf(
            "placeId" to "hello1234"
        ))
    } {
        Text("Back with result")
    }
}
fun onBack(data: Map<String, Any>? = null) {
    if (data != null) {l
        navController.previousBackStackEntry?.savedStateHandle?.let {
            for ((key, value) in data) {
                it.set(key, value)
            }
        }
    }
    navController.popBackStack()
}

NavHost Composable

NavHost(navController = navController, startDestination = Screen.Home.route) {
    composable("card?cardId={cardId}",
        arguments = listOf(
            navArgument("cardId") {
                type = NavType.StringType
                nullable = true
                defaultValue = null
            }
        ))
    { backStackEntry ->

        CardScreen(
            viewModel = hiltViewModel(),
            cardId = backStackEntry.arguments?.getString("cardId"),
            // maybe backStackEntry.savedStateHandle work as well?
            savedStateHandle = navController.currentBackStackEntry?.savedStateHandle) 

    }
}

Composable Screen which receive result

@Composable
fun CardScreen(
    viewModel: CardViewModel = viewModel(),
    cardId: String? = null,
    savedStateHandle: SavedStateHandle?,
) {
    if (savedStateHandle != null) {
        val placeId by savedStateHandle.getLiveData<String>("placeId").observeAsState()
        LaunchedEffect(placeId) {
            placeId?.let {
                // do something
                savedStateHandle.remove<String>("placeId")
            }
        }
    }
}

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.