Skip to content

Instantly share code, notes, and snippets.

@humblehacker
Last active October 4, 2024 19:17
Show Gist options
  • Select an option

  • Save humblehacker/0eb6458b1df6cf3049e031f36f0615f5 to your computer and use it in GitHub Desktop.

Select an option

Save humblehacker/0eb6458b1df6cf3049e031f36f0615f5 to your computer and use it in GitHub Desktop.
Don't expose MutableLiveData

Don't expose MutableLiveData

MutableLiveData Example
MutableLiveData Example

Transformation Setup

The third item is about where and when to create your transformations and this is all about wiring. It's similar to when you create a circuit. You lay down your components and you wire everything up. And for a known set of inputs you're going to have a known set of outputs. You don't unplug a wire while it's in operation and plug it somewhere else, right?

This is exactly what this view model is doing. Lots of horrible things happening in this view model, by the way. For starters ...

Don't do this
screen shot 2018-12-21 at 9 31 03 am

B: You should [show] "don't do this" on this slide

A: It says "don't do this", literally.

B: I'm sure someone will copy/paste it and blame us for recommending it.

A: That's the standard way of doing it.

A: So first, it's exposing itemData, which is a variable. It's a [var] not a [val]. And also, it's exposing a MutableLiveData. Almost ... You should almost never do this. Two-way DataBinding is an exception to this, maybe. You should always expose something that is immutable so your observers can't change it.

...

@adam-hurwitz
Copy link

adam-hurwitz commented Mar 30, 2019

Fantastic organization of best practice notes across various talks! This is exactly what I was looking for in terms of seeing more details after watching the 2018 Android Summit discussion, Fun with LiveData.

I understand the need for creating getter and setter points for LiveData in the ViewModel. However, I am looking to understand how the get() syntax works.

ie:

val isRealtime: LiveData<Boolean>
    get() = _isRealtime
private val _isRealtime = MutableLiveData<Boolean>()

Here is a good explanation on Stackoverflow: How Does Android LiveData get() syntax work?

get() is not related to Android.

val isRealtime: LiveData<Boolean>
    get() = _isRealtime

Here, get() is overriding the automatically-generated Kotlin getter function for the isRealtime property. So, instead of returning its own value, it returns the value of _isRealtime.
Personally, I recommend simpler syntax:

private val _isRealtime = MutableLiveData<Boolean>()
val isRealtime: LiveData<Boolean> = _isRealtime

The objective of either of these is to keep the mutability private, so consumers of this class do not accidentally update the MutableLiveData themselves.

@igorwojda
Copy link

igorwojda commented May 15, 2020

I find this method the best - mainly because less typing (better working code completion)

private val mutableLiveData = MutableLiveData<State>()
val liveData = _liveData.asLiveData()

fun <T> MutableLiveData<T>.asLiveData() = this as LiveData<T>

More ways here

@mobilekosmos
Copy link

mobilekosmos commented Jul 16, 2022

"And also, it's exposing a MutableLiveData. Almost ... You should almost never do this." I'm not so sure about this, for one time shots, for example when wanting to show an error Toast or similar it's handy to have a public mutableLiveData(null) in your ViewModel which is observed in your activity, when you set the value the observer can show the error and then set the value to null, instead of calling another function of the ViewModel to reset the value which I would find to be too much of an overhead for nothing. And this is actually also being done in Google's codelab "Advanced Coroutines"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment