Search code examples
androidkotlinandroid-viewmodelandroid-mvvm

How to call a ViewModel method from another one in android kotlin?


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.


Solution

  • 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
         }
    
    }