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 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 PMMarc Knaup
08/13/2019, 2:34 PMAdam Powell
08/13/2019, 2:34 PMval fromUi = Channel<State>(Channel.CONFLATED)
val ld = liveData {
if (latestValue == null) {
emit(suspendingLoadDataFromDb())
}
for (state in fromUi) {
emit(state)
}
}
fromUi.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 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