In my project I'm using a slightly modified repository pattern:
- DataSource (e.g. API, database). Provides CRUD of entities
- Repository of specific data (e.g. UserRepository, SettingsRepository) that handles reconciliation of DataSources (e.g. update database from API call). Provides basic functionality above CRUD
- ViewModel that uses repositories and creates a flow out of the calls of repositories (e.g. use UserRepository to sync user data, then SettingsRepository to sync settings for the user)
- View is databound
In my Repositories, I use exposed LiveData<*> fields to communicate state - e.g. said UserRepository would have a currentUser
field of public type LiveData, privately MediatorLiveData, and it would be linked to a private field that holds the current user ID to be retrieved.
However, these subscriptions (using MediatorLiveData's addSource() {}
method) for some reason do not fire.
An almost 1:1 example (replaced model name due to NDA) would be the following:
abstract class BaseRepository: ViewModel(), KoinComponent {
val isLoading: LiveData<Boolean> = MutableLiveData<Boolean>().apply { postValue(false) }
}
class UserRepository: BaseRepository() {
private val client: IClient by inject() // Koin injection of API client
private val sharedPref: SharedPrefManager by inject() // custom wrapper around SharedPreferences
private val currentUserId = MutableLiveData()
val currentUser: LiveData<User> = MediatorLiveData()
val users: LiveData<List<User>> = MutableLiveData()
init {
(currentUser as MediatorLiveData).addSource(currentUserId) { updateCurrentUser() }
(currentUser as MediatorLiveData).addSource(users) { updateCurrentUser() }
(currentUserId as MutableLiveData).postValue(sharedPref.getCurrentUserId())
// sharedPref.getCurrentUserId() will return UUID? - null if
}
fun updateCurrentUser() {
// Here I have the logic deciding which user to push into `currentUser` based on the list of users, and if there's a `currentUserId` present.
}
}
With this example implemented, updateCurrentUser()
never gets called, even though the subscription to the other LiveData fields happens and is visible while debugging on the currentUser
object.
The same subscription via addSource
works just fine in other repositories, and they're constructed the very same way as above.
What could be going wrong here?