Marc Knaup
08/12/2019, 9:15 PMval myData = liveData { … } extension.
How can I achieve the same with MutableLiveData? There is no mutableLiveData { … }.
1. Load document from DB using a coroutine upon activation (onActive).
2. Update view model when Fragment requests changes & save them to DB (also using a coroutine).Dominaezzz
08/12/2019, 9:18 PMMutableLiveData<...>()? Or just liveData { ... }?louiscad
08/12/2019, 9:28 PMonActive is when you enter the liveData { } lambda. You can here perform your DB loading, and then loop over a channel for the change requests coming from the Fragment.Marc Knaup
08/12/2019, 9:52 PMMutableLiveData() cannot be passed a coroutine for initialization.
liveData {} is not mutable directly. I thought about looping over a channel but thought it to be unnecessary complicated for a rather simple use case. I just hope that there is a better solution 😕Mark Murphy
08/12/2019, 10:20 PMLiveData handed to your liveData { } code is a MutableLiveData, as CoroutineLiveData extends MediatorLiveData, which is a MutableLiveData. See https://androidx.tech/artifacts/lifecycle/lifecycle-livedata-ktx/2.2.0-alpha03-source/androidx/lifecycle/CoroutineLiveData.kt.html.
You might consider filing a feature request for mutableLiveData { }. What isn't clear to me from the current code is whether the CoroutineLiveData will support other things updating it independent of its coroutine. If it does, then mutableLiveData { } should be just a clone of liveData { } with the MutableLiveData type.Adam Powell
08/13/2019, 1:36 AMAdam Powell
08/13/2019, 1:37 AMAdam Powell
08/13/2019, 1:51 AMAdam Powell
08/13/2019, 1:52 AMMarc Knaup
08/13/2019, 3:42 AMMelih Aksoy
08/13/2019, 9:13 AMliveData { } is a scoped builder you can use if you contracted your return type to LiveData. Return type could be very well a Flow or T generic itself.
If you separate LiveData that you observe for UI from LiveData that feeds your VM with data and relate them with transformations -MediatorLiveData, you won’t need to make it mutable.Marc Knaup
08/13/2019, 11:49 AMMelih Aksoy
08/13/2019, 12:55 PM//Assume repo.getData() returns liveData { ... }
class MyViewModel(private val repo: Repository) : ViewModel() {
val textData: LiveData<Data>
get() = repo.getData().map {
it.textToDisplay
}
}Marc Knaup
08/13/2019, 2:19 PMtextToDisplay be a MutableLiveData and use switchMap instead of map. Then it would be as I’ve written above:
>>Do you mean that the VM live data uses two sources, DB & UI? The latter is then another live data which is mutable and contains the changes from the UI and both will be merged?
Adam Powell
08/13/2019, 2:22 PMMarc Knaup
08/13/2019, 2:22 PMAdam Powell
08/13/2019, 2:23 PMMarc Knaup
08/13/2019, 2:26 PMAdam Powell
08/13/2019, 2:27 PMMarc Knaup
08/13/2019, 2:28 PMAdam Powell
08/13/2019, 2:31 PMAdam Powell
08/13/2019, 2:33 PMAdam Powell
08/13/2019, 2:33 PMAdam Powell
08/13/2019, 2:34 PMMarc Knaup
08/13/2019, 2:34 PMAdam Powell
08/13/2019, 2:34 PMAdam Powell
08/13/2019, 2:37 PMval fromUi = Channel<State>(Channel.CONFLATED)
val ld = liveData {
if (latestValue == null) {
emit(suspendingLoadDataFromDb())
}
for (state in fromUi) {
emit(state)
}
}Adam Powell
08/13/2019, 2:38 PMAdam Powell
08/13/2019, 2:39 PMfromUi.offer(stateFromUi) as the implementation of whatever ViewModel method you're using to get data in thereMarc Knaup
08/13/2019, 2:40 PMlouiscad
08/13/2019, 2:40 PMAdam Powell
08/13/2019, 2:40 PMAdam Powell
08/13/2019, 2:40 PMlouiscad
08/13/2019, 2:41 PMAdam Powell
08/13/2019, 2:41 PM/!=` 😅 for the is-initialized check)Marc Knaup
08/13/2019, 2:44 PMSavedStateHandle 😄
Initial load from DB -> load from saved state if present -> incremental updates on UI