Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LiveData: Remove observer from inside Observer lambda

Inside my fragment i'm observe a livedata:

 viewModel.emailValid.observe(
     this,
     Observer<GenericResponse> {
         dismissProgressBar()
         if (it != null && it.success) {
             findNavController().navigate(R.id.action_navigatesomewhere)
         }
     }
)

now before calling navigate(), i would like to remove observer from viewModel.emailValid and i've see that is available removeObserver method that require the observer as parameter. It's possible to reference in some way the observer inside the observer lambda?

like image 898
giozh Avatar asked Oct 18 '19 09:10

giozh


2 Answers

First of all, since you are not calling observeForever(), but just calling observe() in order to observe a livedata from an object that has a lifecycle, you probably don't need to remove the observer – it will be ignored/removed automatically by the system when the subscriber stops being active.

However, if you really need to remove the observer manually for whatever reason, you will have to save your observer into a property. That way, you will later be able to pass the observer as a parameter to the method removeObserver():

// Define your observer as a property
private val emailValidObserver = Observer<GenericResponse> { onEmailValidChanged(it) }

...

private fun onEmailValidChanged(emailValidResponse: GenericResponse) {
    dismissProgressBar()
    if (emailValidResponse != null && emailValidResponse.success) {
        findNavController().navigate(R.id.action_navigatesomewhere)
    }
}

...

// Observe the livedata with the observer you have defined
viewModel.emailValid.observe(this, emailValidObserver)

...

// Stop observing the livedata
shoppingListName.removeObserver(emailValidObserver)

On the other hand, if at some point you want to remove all the observers associated with your lifecycle instance, you can just call this method:

removeObservers(this)
like image 172
Julio E. Rodríguez Cabañas Avatar answered Oct 11 '22 21:10

Julio E. Rodríguez Cabañas


You can use an anonymous object for it:

viewModel.emailValid.observe(
     this,
     object : Observer<GenericResponse> {
         override fun onChanged(it: GenericResponse?) {
             viewModel.emailValid.removeObserver(this)
             dismissProgressBar()
             if (it != null && it.success) {
                 findNavController().navigate(R.id.action_navigatesomewhere)
             }
         }
     }
)
like image 44
Andrei Tanana Avatar answered Oct 11 '22 23:10

Andrei Tanana