architecture-components-samples icon indicating copy to clipboard operation
architecture-components-samples copied to clipboard

Can one viewmodel consist of another viewmodel

Open prabinshrestha opened this issue 7 years ago • 8 comments

I have DashBoardViewModel which will provide the data of message,news,events etc for my DashBoardActivity.So is it appropraite to use MessageViewModel,NewsViewModel etc as a member of DashBoardViewModel.

Is this approach bad or good?

public class DashBoardViewModel extends AndroidVIewModel{

private MessageViewModel mvm; private NewsViewModel nvm;

public LiveData<List<News>> getData(){ return nvm.getNewsList(); }

}

prabinshrestha avatar Nov 16 '17 06:11 prabinshrestha

@prabinshrestha Don't place your ViewModel into another ViewModel. You should provide your ViewModel from ViewModelProviders. ViewModelProviders needs a context to create your ViewModel with given type.

There is nothing wrong with providing multiple ViewModel for a single activity.

iammert avatar Dec 21 '17 16:12 iammert

Sometimes you need composition in the view model layer though. Some view models can be "derived" from others. You don't want to have this logic in the presentation layer.

ivnsch avatar May 11 '18 15:05 ivnsch

I agree with i-schuetz.

Right now it is possible to compose multiple ViewModels inside the presentation layer (activity) like this:

ViewModelProviders.of(this, viewModelFactory).get(FirstViewModel::class.java) ViewModelProviders.of(this, viewModelFactory).get(SecondViewModel::class.java)

The problem is that some logic might be required in the presentation layer (activity) to interact with both those ViewModels.

I would like to be able to compose multiple ViewModels inside a ViewModel. That way the presentation layer will be bound to a single ViewModel which internally will include multiple ViewModels.

Right now this is not possible, because ViewModelProviders.of() requires an activity as the first parameter and can not be used from another ViewModel.

georgiptr avatar Aug 27 '18 08:08 georgiptr

Hi people,

I totally agree with @ggeorgip: as long as we can have access to several ViewModels in the view, I don't understand how we would be able to combine their data (maybe we shouldn't need to and that's the error) without giving a VM to another (except from handling the combination in the view, which I very much dislike)...

Any advice about this?

Thanks

m0rgan-plot avatar Dec 11 '18 17:12 m0rgan-plot

Total agree with @ggeorgip

@iammert Composing ViewModels will help to remove communication code(to pass data from one ViewModel to another) from presentation layer (Fragment, View etc.) On the other hand we will still have the possibility to have that view models separated and tested properly.

amatkivskiy avatar Jan 02 '19 10:01 amatkivskiy

I have a list of lets say "movies" i can have list of movies as mutableLiveData and set Observers on it on my presentation layer but what if i want to set Observer on single instance of movie's atrribute?

rawbi avatar Jan 13 '21 03:01 rawbi

I have done similar in my project, this is working using Koin

val module = module {
    viewmodel { SharedViewModel() }   // this is a activity viewmodel
    viewmodel { (shared: SharedViewModel) -> FragmentViewModel(shared) }
}

class SharedViewModel() : ViewModel() {
   val sharedData: String = ""
}

class FragmentViewModel(private val shared: SharedViewModel) : ViewModel() {
    val fragmentUsesSharedData = shared.sharedData
}

class Fragment: Fragment() {
    val fragmentViewmodel: FragmentViewModel by viewModel {
             parametersOf(getSharedViewModel<SharedViewModel>())
    }


    fun test() {
      println(fragmentViewModel.fragmentUsesSharedData)
    }
}

VishnuPrabhu avatar Apr 05 '21 07:04 VishnuPrabhu

In my case I have to call 3 different APIs to fetch data from different services, in order to display this data in a RecyclerView I have to create an adapter and it can only have one ViewModel -- how does one go about it in this case? Thanks.

hellocaio avatar Dec 15 '22 12:12 hellocaio