I am using Transformations.switchMap in my ViewModel so my LiveData
collection, observed in my fragment, reacts on changes of code
parameter.
A simplification of jL4's answer, (and also in Kotlin in case it helps anybody)... no need to create a custom class for this:
class YourViewModel: ViewModel() {
val firstLiveData: LiveData // or whatever type
val secondLiveData: LiveData // or whatever
// the Pair values are nullable as getting "liveData.value" can be null
val combinedValues = MediatorLiveData>().apply {
addSource(firstLiveData) {
value = Pair(it, secondLiveData.value)
}
addSource(secondLiveData) {
value = Pair(firstLiveData.value, it)
}
}
val results = Transformations.switchMap(combinedValues) { pair ->
val firstValue = pair.first
val secondValue = pair.second
if (firstValue != null && secondValue != null) {
yourDataSource.yourLiveDataCall(firstValue, secondValue)
} else null
}
}
Explanation
Any update in firstLiveData
or secondLiveData
will update the value of combinedValues
, and emit the two values as a pair (thanks to jL4 for this).
Calling liveData.value
can be null, so this solution makes the values in Pair nullable to avoid Null Pointer Exception.
So for the actual results/datasource call, the switch map is on the combinedValues
live data, and the 2 values are extracted from the Pair
and null checks are performed, so you can be sure of passing non-null values to your data source.