0

I have got a UserViewModel which extends AndroidViewModel class, this class has a MutableLiveData of type User which has informations like user credit inside, this view model also has a editCredit method which sets the new amount of credit a user has(saves on DB and postValue the user property so it can be observed in view)

The other AndroidViewModel class that I've got is CourseViewModel which has properties like courseList or currentCourse. it also has a method called buyCourse which needs to reduce the user credit and add that course to the list of users course. the second property lives in CourseViewModel class and I have no trouble updating that list but for reducing user's credit I need to call editCredit method which lives in other viewModel class.

I know I can use some logics in View Layer and call courseViewModel.buyCourse there and then add an observable method so when it added to user's course list, I can be notified and call userViewModel.editCredit in that layer, but my question is:

Is there any way, a viewModel class can call another ViewModel class's methods?

Update ---

Before I start coupling my view models I had one viewModel which contains more than 400 lines of code, but it could do the job easily but was hard to read (there was not much logics there only calling repository functions) So I tried to change them into smaller view model classes and now I am stuck.

4
  • Is there any way, a viewModel class can call another ViewModel class's methods? doesn't seem like a good idea. if one component needs data for it to work, then that data is a dependency and there are known ways of handling dependencies. needing another VM inside your VM is just a way of hiding the fact that you actually need data, which can be passed around Commented Jun 7, 2021 at 12:20
  • Before start coupling your ViewModels with each other I would suggest you to read about ViewModel and what purpose it actually serves within an application. Commented Jun 7, 2021 at 12:24
  • @OhhhThatVarun thanks for your comments, actually I had only one class in the beginning but it started to grow and grow and became a 400+ lines of code (Mostly caling a repository suspend function in ViewModelScope) so as it rows it became harder and harder to read and debug, that was why I tried to split it out into smaller classes, but it seems it is not easy to handle these dependencies, any suggestion? Commented Jun 8, 2021 at 6:00
  • @a_local_nobody thanks for your comment too, actually I was looking for a way of negotiating between viewModels to keep them independent while a huge viewModel can be split into smaller ones, but it seems there is not a standard way for doing that Commented Jun 8, 2021 at 6:04

1 Answer 1

1

As it was already mentioned, you should not do that. ViewModels shouldn't know about each other but if you really need to do this:

what you could potentially do is providing needed method in form of interface. This interface will be extended by one ViewModel and provided to the second one in the initialization using WeakReference (read about that a bit) just to be safe no memory leaks occur.

interface EditCredit {
  fun editCredit()
}
class UserViewModel : EditCredit {
   override fun editCredit() {
      // do sth
   }
}
class CourseViewModel {
  var editCredit: EditCredit? by weak() // by using weak() I just want to indicate you should handle it properly

   fun someFunctionThatNeedsEditCredit() {
      editCredit?.editCredit()
   }
}
class SomeActivity {
     val userViewModel: UserViewModel
     val courseViewModel: CourseViewModel

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        userViewModel = //initialize it
        courseViewModel = //initialize it
        courseViewModel.editCredit = userViewModel
     }

}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks that was a great solution, as you said it might not be the best practice but as it makes my program much easier to read and debug, I believe it worth using

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.