Search code examples
kotlinretrofit2viewmodel

Trying to use ViewModels inside of another ViewModel, Errors with LifecycleObserver and Ownership (Kotlin)


Im trying to get some data out of other ViewModels inside another ViewModel to make my code smaller, but im having a problem trying to implement what already worked on a fragment or in a activity, this is what i got:

class ObraConMediaViewModel(private val context: ViewModelStoreOwner,
                        private val id: Int): ViewModel(), LifecycleObserver {

var allObras: LiveData<ArrayList<ObraConMedia>>

private lateinit var viewModelobras: ViewModelObras
private lateinit var viewModelMediaObra: ViewModelMediaObra

val repositoryobras =ObrasRepository()
val repositoryMediaObra = MediaObraRepository()

val viewModelFactoryobras = ViewModelFactoryObras(repositoryobras)
val viewModelMediaObraFactory = ViewModelMedIaObraFactory(repositoryMediaObra)

init{
    viewModelobras = ViewModelProvider(context, viewModelFactoryobras)
        .get(ViewModelObras::class.java) // requireActivity() when called
    viewModelMediaObra = ViewModelProvider(context, viewModelMediaObraFactory)
        .get(ViewModelMediaObra::class.java)

    viewModelobras.getObras(id)
    viewModelobras.myResponse.observe(this , Observer { response ->
        if (response.isSuccessful){
            Log.d("Response", response.body()?.ans?.get(0)?.autor)
            Log.d("Response", response.body()?.ans?.get(1)?.autor)
        }else{
            Log.d("Response", response.errorBody().toString())
        }})

    viewModelMediaObra.getMediaObra(Constantes.PRUEBA_ID)
    viewModelMediaObra.myResponse.observe(this, Observer { response ->
        if (response.isSuccessful){
            Log.d("Response", response.body()?.ans?.get(0)?.filePath)

        }
    })
}}

I was having trouble with the Observer but extending the class to LifecycleObserver fixed it, i have no idea if this will even work but the only error that i have right now its the owner of the .observe(this,....), i dont seem to find a way to pass a lifecycleowner from the fragment to this viewmodel. All the variables i need to make this viewmodel work are inside those two responses. If this is a very bad way to do it please tell me. Thanks for reading.


Solution

  • Kindly note that above approach is not correct.
    One should not create a instance of ViewModel inside another ViewModel.
    There is a possibility that one ViewModel may get destroyed before another. This will lead to garbage reference and memory leaks.

    I would recommend you to create the instance of both View Models in an Activity/Fragment and then call respective methods of ViewModel from Activity/Fragment.

    Also, as you want to make your code smaller and concise, I highly recommend you Shared ViewModel.
    This Shared ViewModel can be used by two fragments.
    Please refer to this link