3.2.0 cant get viewModel
Hello. Thanks for your library.
I`m using your library with Voyager (https://voyager.adriel.cafe/). I have code to get viewModel from AndroidScreen from Voyager.
` @Composable fun AndroidScreen.getComposeViewModelOwner(): ViewModelOwner = ViewModelOwner.fromAny(getLifecycleOwner())
@OptIn(KoinInternalApi::class) @Composable inline fun <reified T : ViewModel> AndroidScreen.getScreenViewModel( qualifier: Qualifier? = null, owner: ViewModelOwner = getComposeViewModelOwner(), scope: Scope = GlobalContext.get().scopeRegistry.rootScope, noinline parameters: ParametersDefinition? = null, ): T = remember(qualifier, parameters) { scope.getViewModel(qualifier, { owner }, parameters) } `
But after last update (3.2.0) i can`t get scope.getViewModel function (not found) and ViewModelOwner is deprecated. Can you help me solve this issue after update? Thanks
@arnaudgiuliani what do you suggest as a solution for this issue, I'm had le same problem when trying migrate from v2 -> v3 no scope.viewModel found
I guess we can use something like this:
val ourSession = getKoin().getOrCreateScope("ourSession", named<OurActivity>()).let {
scope.linkTo(it)
}
private val viewModel by viewModel<OurViewModel> { parametersOf(this) }
ViewModelOwner is deprecated in favor of using directly ViewModelStoreOwner. A ViewModelStoreOwner is an Activity, Fragment, NavBackStackEntry ...
Aligned to the koin internals managed to workaround it like this:
@OptIn(KoinInternalApi::class)
inline fun <reified T : ViewModel> Fragment.viewModelScoped(
scope: Scope? = null ,
noinline parameters: ParametersDefinition? = null,
): Lazy<T> {
val owner = { this }
return viewModels(
ownerProducer = owner,
factoryProducer = {
val localScope = scope ?: GlobalContext.get().scopeRegistry.rootScope
getViewModelFactory<T>(
owner = owner(),
qualifier = null,
parameters = parameters,
scope = localScope,
)
})
}
And if you need it non-lazy just call viewModelScoped.value
So maybe there is a similar workaround with the compose extensions :)
@akoell I've had to tweak your solution a bit to get the desired effect. Here's my variant:
@OptIn(KoinInternalApi::class) inline fun <reified T : ViewModel> Fragment.viewModelScoped( scope: Scope? = null, owner: ViewModelStoreOwner = this, noinline parameters: ParametersDefinition? = null, ): Lazy<T> { val localOwner = { owner } return viewModels( ownerProducer = localOwner, factoryProducer = { val localScope = scope ?: GlobalContext.get().scopeRegistry.rootScope getViewModelFactory<T>( owner = localOwner(), qualifier = null, parameters = parameters, scope = localScope, ) }) }
it's a problem of passing your scope here?
Actually, I've managed to get the desired result just by linking scopes and setting the correct viewmodel owner.
@arnaudgiuliani I'm having similar issue, on this 3.1->3.2 migration but on the case that we have an isolated Koin context (https://insert-koin.io/docs/reference/koin-core/context-isolation) on our SDK project.
The only way I could find to make it work was to use internal APIs:
getViewModel(
scope = isolatedKoin.scopeRegistry.rootScope,
parameters = parameters
)
but those got errors and forced to add an @OptIn(KoinInternalApi::class).
Is using the internal API the only way to achieve that? Maybe there's something else I missed?
Thanks.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.