10

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?

Giorgos Neokleous
  • 1,709
  • 1
  • 14
  • 25
giozh
  • 9,868
  • 30
  • 102
  • 183
  • You can use removeObservers method. This will remove all observers. If you use removeObserver it requires the observer as the parameter to remove it. – channae Oct 18 '19 at 09:55

2 Answers2

7

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)
  • The remove observers is about the only thing that worked for me. Livedata still firing twice but now its not holding onto a previous value from a different fragment. – JPM Nov 15 '21 at 23:13
2

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)
             }
         }
     }
)
Andrei Tanana
  • 7,932
  • 1
  • 27
  • 36