Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Android Livedata Observe Once Only (Kotlin)
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
observe(lifecycleOwner, object : Observer<T> {
override fun onChanged(t: T?) {
observer.onChanged(t)
removeObserver(this)
}
})
}
//Using
liveData.observeOnce(this, Observer<Password> {
if (it != null) {
// do something
}
})
val liveData = viewModel.showSnackBar("Hi everyone")
liveData.observe(this, object: Observer<String> {
override fun onChanged(text: String?) {
liveData.removeObserver(this)
}
})
@DavidJH2
Copy link

DavidJH2 commented Jul 26, 2021

I have had good use of this pattern however in one of my use cases when I set up the observer of an existing value, I get an immediate call back before the observed value has changed. My understanding is that it only works if the initial value starts as null. Is this correct and if so what is the solution if the value has a non-null value?

Thanks!

@DavidJH2
Copy link

DavidJH2 commented Jul 26, 2021

Just created this LiveData extension function:

fun <T> LiveData<T>.observeOnceAfterInit(owner: LifecycleOwner, observer: (T) -> Unit) {
	var firstObservation = true
	
	observe(owner, object: Observer<T>
	{
		override fun onChanged(value: T) {
			if(firstObservation)
			{
				firstObservation = false
			}
			else
			{
				removeObserver(this)
				observer(value)
			}
		}
	})
}

Would this be the best way to ignore the initial call back after observer setup

@kobeumut
Copy link
Author

kobeumut commented Aug 1, 2021

Hello David, I'm not sure what is the best solution for it but you are right. And also your script that wrote above is going to work properly.

@DavidJH2
Copy link

DavidJH2 commented Aug 1, 2021

Great, thanks for the reply!

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