question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Possible solution for Arch ViewModel dynamic parameters

See original GitHub issue

After seeing Jake’s presentation on this library at DroidCon, I was hoping that the proposed solution will solve the problem of passing dynamic parameters to Android Architecture Components ViewModel that is discussed on several places over the internet, originally probably here https://github.com/googlesamples/android-architecture-components/issues/207

Since ViewModel shouldn’t be injected directly to a client as Presenter is in the examples of this library and Jake’s talk, all I could come up with was double factories, the assisted factory for creating ViewModelFactory and then then ViewModelFactory to have the system lazily create the ViewModel.

Can someone see a better solution or would it require a specific fork of this library to auto generate this extra ViewModelFactory?

Ideally I would see the same solution as in Jake’s presentation. No manual creation of ViewModel and no manual parameter passing, only the dynamic params to Factory create method.

My example: The ViewModelFactory and “ViewModelFactoryFactory”

class WordDetailViewModelFactory @AssistedInject constructor(
    private val repository: WordRepository,
    @Assisted private val argument: WordDetailScreenArg
) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return WordDetailViewModel(repository, argument) as T
    }

    @AssistedInject.Factory
    interface Factory {
        fun create(argument: WordDetailScreenArg): WordDetailViewModelFactory
    }
}

The ViewModel

class WordDetailViewModel(
    private val repository: WordRepository,
    argument: WordDetailScreenArg
) : ViewModel() {

    val wordDetail: LiveData<Word> = repository.word(argument.word)

    fun onDeleteWordClicked() {
        wordDetail.value?.let {
            repository.deleteWord(it.word)
        }
    }
}

Injection

@Inject
lateinit var viewModelFactory: WordDetailViewModelFactory.Factory;

override fun onAttach(context: Context?) {
    super.onAttach(context)

    val arguments: WordDetailScreenArg = ...
    Injection.appComponent.inject(this)

    viewModel = ViewModelProviders.of(this, viewModelFactory.create(arguments))[WordDetailViewModel::class.java]

}

Edit: looks like @hansenji has a solution at https://github.com/hansenji/ViewModelInject

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

14reactions
JakeWhartoncommented, Apr 20, 2020

This functionality is going to be covered by the upcoming Hilt tool in Jetpack which integrates Dagger with view models and work manager.

0reactions
hansenjicommented, Apr 20, 2020

This library uses Assisted Inject and SavedStateHandle to pass arguments into your viewmodel https://github.com/hansenji/ViewModelInject.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Possible solution for Arch ViewModel dynamic parameters #71
After seeing Jake's presentation on this library at DroidCon, I was hoping that the proposed solution will solve the problem of passing ...
Read more >
Android ViewModel additional arguments - Stack Overflow
I don't recommend this way because couple of reasons: 1) parameters in factory are not type safe - this way you can break...
Read more >
Has anyone figured how to properly inject ViewModels that ...
Now the trick here is that you can only access the runtime arguments from the enclosing scope, therefore this means that your ViewModelProvider....
Read more >
Saved State module for ViewModel - Android Developers
This object is a key-value map that lets you write and retrieve objects to and from the saved state. These values persist after...
Read more >
How to Use String Resources In a ViewModel - YouTube
Whenever possible, you should be using string resources to make sure your app can easily be translated to other languages. However to read...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found