Closed ahmadhassan5 closed 1 year ago
Thanks for the reply.
I'm using same approach but how can I inject 'noteDataSource' in this case (for example, I'm using Koin)
val viewModel = viewModel(NoteListViewModel::class) { NoteListViewModel(noteDataSource = ?) }
You can use the get()
function in koin to get the parameter you want like this:
val noteDataSource: NoteDataSource = get()
val viewModel = viewModel(NoteListViewModel::class) {
NoteListViewModel(noteDataSource = noteDataSource)
}
or you can check out here as an example
Thank you for the assistance. I think, you mentioned another file mistakenly. Anyway, I used the extension function from ComposeExt.
One more thing, I placed logs inside scene composables, they were triggered multiple times on single event. I don’t, it’s expected behaviour. Isn’t it?
Since PreCompose uses AnimatedContent
for navigation animation, at some point there will be two screens displayed at the same time, as long as you're not doing heavy stuff in Compose, this is fine.
Close as inactive.
Hi I have the same problem How can I define preCompose ViewModel by Koin?
It is normally as follows :
module {
single { UserRepository(client = get()) }
viewModel { UserViewModel(userRepository = get()) }
}
and for use :
private val viewModel: UserViewModel by viewModel()
But how can I use it for your library?
Hi I have the same problem How can I define preCompose ViewModel by Koin?
It is normally as follows :
module { single { UserRepository(client = get()) } viewModel { UserViewModel(userRepository = get()) } }
and for use :
private val viewModel: UserViewModel by viewModel()
But how can I use it for your library?
You can check out here as an example, simply define a factory
and it should work as expected.
inline fun <reified T : ViewModel> Module.viewModel(
qualifier: Qualifier? = null,
noinline definition: Definition<T>
): Pair<Module, InstanceFactory<T>> {
return factory(qualifier, definition)
}
@KoinReflectAPI
inline fun <reified T : ViewModel> Module.viewModel(
qualifier: Qualifier? = null
): Pair<Module, InstanceFactory<T>> {
return factory(qualifier) { newInstance(it) }
}
I deleted the second function and changed the first function to the following code, it was fixed.
inline fun <reified T : ViewModel> Module.viewModel(
qualifier: Qualifier? = null,
noinline definition: Definition<T>
): KoinDefinition<T> {
return factory(qualifier, definition)
}
I did using this extension function. Check this repository!
inline fun <reified T : ViewModel> Module.viewModel( qualifier: Qualifier? = null, noinline definition: Definition<T> ): Pair<Module, InstanceFactory<T>> { return factory(qualifier, definition) } @KoinReflectAPI inline fun <reified T : ViewModel> Module.viewModel( qualifier: Qualifier? = null ): Pair<Module, InstanceFactory<T>> { return factory(qualifier) { newInstance(it) } }
I deleted the second function and changed the first function to the following code, it was fixed.
inline fun <reified T : ViewModel> Module.viewModel( qualifier: Qualifier? = null, noinline definition: Definition<T> ): KoinDefinition<T> { return factory(qualifier, definition) }
@mahramane
Your fix seems to work in the module definition, but I still can't acquire the viewmodel like private val viewModel: UserViewModel by viewModel()
in the Activity:
Type mismatch.
Required: UserViewModel
Found: ViewModel
How exactly did you manage to get that working? For context, I'm trying to share viewmodels between a regular android app and a compose app. Thank you in advance.
You must use the following code in compose:
val androidModule = module {
single { MyService() }
}
@Composable
fun App() {
val myService = koinInject<MyService>()
}
@Composable
fun App(myService: MyService = koinInject()) {
}
Yeah your suggestion is correct but I think my use case is just wrong. I am trying to find a no-boilerplate way to share viewmodels between a regular android app and a compose app but that's probably not what precompose is intended for. Thanks for your help though, I appreciate it.
@sleeyax Check this repository, this is Compose Multiplatform app with shared ViewModel. Koin as DI.
How are you guys using Koin's get
exactly?
For example the following suggestion doesn't work for me within a composable:
val noteDataSource: NoteDataSource = get() val viewModel = viewModel(NoteListViewModel::class) { NoteListViewModel(noteDataSource = noteDataSource) }
What does work is the following:
val noteDataSource = koinInject<NoteDataSource>()
val viewModel = viewModel(NoteListViewModel::class) {
NoteListViewModel(noteDataSource = noteDataSource)
}
I can only seem to import koinInject
here, not get
. Is this normal? It appears to achieve the same result either way but I'm not sure why this is the case.
I have defined the extension function. Check here
Since the Compose compiler does not work well with inline composable for the Kotlin Native platform, you can use non-inline version of
viewModel
like this: