koin icon indicating copy to clipboard operation
koin copied to clipboard

SavedStateHandle doesn't contain navigation arguments

Open grrigore opened this issue 2 years ago • 9 comments

I'm trying to inject SavedStateHandle. I am using Koin, Jetpack Compose and Navigation. I've managed to make it work, but I think it's not the right instance (I don't get my values).

This is what I do so far:

Setting the argument:

private fun NavGraphBuilder.addDetails(
    navController: NavHostController,
    root: Screen
) {
    composable(route = LeafScreen.Details.createRoute(root),
        arguments = listOf(
            navArgument("showId") { type = NavType.LongType }
        )) {
        DetailsScreen(navigateUp = navController::navigateUp)
    }
}

Defining my ViewModel:

internal class DetailsViewModel(
    val handle: SavedStateHandle,
    private val getMovieDetailsUseCase: GetMovieDetailsUseCase
) : ViewModel() 

Defining my composable:

@Composable
fun DetailsScreen(
    navigateUp: () -> Unit
) {
    DetailsScreen(
        viewModel = getStateViewModel(),
        navigateUp = navigateUp,
    )
}

And my modules:

val uiDetailsModules = module {
    viewModelOf(::DetailsViewModel)
}

It runs but showId from val showId = handle.get<Long>("showId") is null.

grrigore avatar May 24 '22 11:05 grrigore

I have also tried using viewModel { (handle: SavedStateHandle) -> DetailsViewModel(handle, get()) }

grrigore avatar May 24 '22 11:05 grrigore

Hello! The same thing is happening to me, I think the case is related. According to the google changelog it should pick up the arguments via SavedStateHandle

https://developer.android.com/jetpack/androidx/releases/navigation#2.4.0

But this does not happen, here is my example.

Module:

viewModel { (handle: SavedStateHandle) ->TestViewModel(savedStateHandle = handle) }

Fragment:

val viewModel: TestViewModelby stateViewModel()

ViewModel:

class TestViewModelby (savedStateHandle: SavedStateHandle)

Looking at the debug tab it seems that SavedStateHandle does not pick up the arguments from viewmodel

image

But if I look at the test arguments in the Fragment, it does have arguments.

image

If I try this using test by viewmodels() //androidx.fragment.app.viewModels

It seems that if I get the arguments of the args from SavedStateHandle in the viewmodel, here is an example:

image

I hope this helps to fix this :)

Thanks!

buhho-crtl avatar May 26 '22 11:05 buhho-crtl

Let's hope its available soon 😃 https://github.com/InsertKoinIO/koin/pull/1286

rubenquadros avatar May 30 '22 18:05 rubenquadros

Thank you very much! :D

buhho-crtl avatar May 31 '22 09:05 buhho-crtl

Looks like a good candidate for the patch. Any plans to release 3.2.1 with it?

Gwindor avatar Jun 21 '22 14:06 Gwindor

Please review the pr which conforms with 3.2 https://github.com/InsertKoinIO/koin-compose/pull/3

rubenquadros avatar Jul 05 '22 17:07 rubenquadros

Still stuck with this one.

grrigore avatar Jul 13 '22 08:07 grrigore

Me too.

cvb941 avatar Jul 13 '22 08:07 cvb941

Workaround

private val EmptyBundle = Bundle()

fun Fragment.argumentsToBundleDefinition(): BundleDefinition = {
    if (arguments != null)
        arguments!!
    else
        EmptyBundle
}

inline fun <reified VM : ViewModel> Fragment.injectViewModel(
    qualifier: Qualifier? = null,
    noinline state: BundleDefinition = argumentsToBundleDefinition(),
    noinline owner: ViewModelStoreOwnerProducer = { this },
    noinline parameters: ParametersDefinition? = null,
): Lazy<VM> = stateViewModel(qualifier, state, owner, parameters)

qavan avatar Jul 22 '22 08:07 qavan

Should be fixed in koin-androidx-compose 3.2.1

PR https://github.com/InsertKoinIO/koin-compose/pull/3 has been merged

arnaudgiuliani avatar Sep 06 '22 14:09 arnaudgiuliani

Thanks @arnaudgiuliani from 3.2.1 the SavedStateHandle started storing navigation arguments using getViewModel composable

szyman avatar Oct 07 '22 14:10 szyman