Hi :wave: , I hope that one of you can be of help to me with my current issue :pray: I have created...
n
Hi 👋 , I hope that one of you can be of help to me with my current issue 🙏 I have created a BaseViewModel that two different ViewModels VM1 and VM2 extend in hopes of sharing data and some functions used in both places.
Copy code
abstract class OnboardingBaseViewModel(
    private val postNotificationSchemeUseCase: PostNotificationSchemeUseCase,
    private val putUserPropertyUseCase: PutUserPropertyUseCase
) : ViewModel() {
    // Data that needs to be shared 
    val _customOptionItems = MutableLiveData<List<CustomOptionItem>>()
    val customOptionItems = _customOptionItems
}
Upon my init function in VM1 I want to access the data already set from VM2 however it's null. VM2 is created like this:
Copy code
@HiltViewModel
class RemindersTimeViewModel @Inject constructor(
    postNotificationSchemeUseCase: PostNotificationSchemeUseCase,
    putUserPropertyUseCase: PutUserPropertyUseCase
) : OnboardingBaseViewModel(postNotificationSchemeUseCase, putUserPropertyUseCase)
{
init{
// this is null - but why?
val data = customOptionsItems.value
}
}
I inject the viewmodels into the fragments with Hilt like so:
Copy code
private val viewModel: RemindersViewModel by activityViewModels()
a
Inheriting from a base class means that VM1 and VM2 each have their own
customOptionItems
, not that all VM1s and VM2s share the same
customOptionItems
🙌 1
p
You are instantiating a new object that has no knowledge of the other object you've created, even if they are the same type. You can't inherit state that way. One solution might be to use a repository (or usecase, same thing) that holds the state data you need to share across ViewModels, and inject them into your ViewModels using Dagger/Hilt.
Copy code
@HiltViewModel
class RemindersTimeViewModel @Inject constructor(
    ...
    provideCustomOptionsItemsUseCase: CustomItemsUseCase 
) : OnboardingBaseViewModel(postNotificationSchemeUseCase, putUserPropertyUseCase)
Copy code
class CustomItemsUseCase(){
...
 private val _customOptionItems = MutableLiveData<List<CustomOptionItem>>()
    val customOptionItems = _customOptionItems
}
You could then store those
CustomOptionItems
as persistent data using Room, or you could provide
CustomItemsUseCase
as a
@Singleton
so that Dagger only instantiates one
CustomItemsUseCase
object that would be shared across any other classes that inject it (like your ViewModels). Just be aware that there are plenty of pitfalls when using the Singleton pattern
🙌 1
n
Thank you very much for your answers. They have been very helpful 👏 !