From 709428b9af556e9d7373b7158348000425fb6c68 Mon Sep 17 00:00:00 2001 From: Jan Skrasek Date: Fri, 27 Oct 2023 12:08:59 +0200 Subject: [PATCH] fix NPE in result processing when nav controller has not backstack entry intialized yet This fixes some kind of race condition we are not able to properly reproduce. --- .../navigationcompose/typed/ResultSharing.kt | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt b/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt index e8a85da..35e7c51 100644 --- a/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt +++ b/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt @@ -2,9 +2,14 @@ package com.kiwi.navigationcompose.typed import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.navigation.NavController +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.first import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.json.Json @@ -31,9 +36,23 @@ public inline fun , reified R : Any> Composable navController: NavController, noinline block: (R) -> Unit, ) { + // The async waiting workarounds situations when navController.currentBackStackEntry is null + // ~ not yet populated. + val currentDestinationState = remember(navController) { + mutableStateOf(navController.currentDestination) + } + val currentDestination = currentDestinationState.value + if (currentDestination == null) { + LaunchedEffect(navController) { + val currentBackStackEntry = navController.currentBackStackEntryFlow.filterNotNull().first() + currentDestinationState.value = currentBackStackEntry.destination + } + return + } + ResultEffectImpl( navController = navController, - currentRoute = navController.currentDestination!!.route!!, + currentRoute = currentDestination.route!!, // routes are always not null in Nav Compose destinationSerializer = serializer(), resultSerializer = serializer(), block = block,