Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rememberKoinInject() not working when used with parameters [koin-compose:1.0.3] #1601

Closed
mz-efento opened this issue Jun 2, 2023 · 6 comments
Labels
compose status:checking currently in analysis - discussion or need more detailed specs type:issue
Milestone

Comments

@mz-efento
Copy link

mz-efento commented Jun 2, 2023

  • The problem:

In the example below, the coroutineScope is created in the SomeScreen() context, and then it is used as a parameter for koin injection. Even though the same coroutineScope is used in all recompositions, rememberKoinInject() returns new instance of SomeViewModel every time. (model is not actually remembered)

@Composable
fun SomeScreen() {
    val coroutineScope = rememberCoroutineScope()
    val viewModel = rememberKoinInject<SomeViewModel> { parametersOf(coroutineScope) }
    ...
}
  • The (probable) cause:

coroutineScope parameter is wrapped into a lambda behind the scenes, and then then the newly created lambda is passed down the chain to composable remember method as a key for evaluation. The lambda is different each time so evaluation will be re-run reglardless if provided parameter is the same or not.

val viewModel = rememberKoinInject<SomeViewModel> { parametersOf(coroutineScope) }
is eqal to
val viewModel = rememberKoinInject<SomeViewModel>(parameters = { parametersOf(coroutineScope) }) //lambda!
  • The workaround:
    As for now, the workaround is to remember the whole lambda with parameter, and pass the exact same lambda to rememberKoinInject function:
@Composable
fun SomeScreen() {
    val coroutineScope = rememberCoroutineScope()
    val parametersOf: () -> ParametersHolder = remember {
        { parametersOf(coroutineScope) }
    }
    val viewModel = rememberKoinInject<SomeViewModel>(parameters = parametersOf)
    ...
  • The fix
    Providing a working solution that will utilize default rememberKoinInject syntax:
val viewModel = rememberKoinInject<SomeViewModel> { parametersOf(coroutineScope) }
@flopshot
Copy link

Also seeing this bug in 1.0.3

@arnaudgiuliani arnaudgiuliani added type:issue status:checking currently in analysis - discussion or need more detailed specs compose labels Aug 4, 2023
@arnaudgiuliani arnaudgiuliani added this to the compose-1.1.0 milestone Aug 4, 2023
@arnaudgiuliani
Copy link
Member

yes, a tricky issue 👍 will look at it

@hoc081098
Copy link

I think that is expected behavior, since the lambda refs to unstable vars (such as scope), that makes this lambda unstable as well, so the compiler will not remember lambda automatically.

@hoc081098
Copy link

See slackhq/circuit#466

@arnaudgiuliani
Copy link
Member

interesting 👍

@arnaudgiuliani
Copy link
Member

Let's see on koin-compose 1.1.0 how it goes 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compose status:checking currently in analysis - discussion or need more detailed specs type:issue
Projects
None yet
Development

No branches or pull requests

4 participants