2

I have a case where I have BottomNavigationView where fragments are shown/hidden instead of adding/replacing, therefore they do not go through their lifecycle every time.

Fragment 1 is observing one database table, Fragment 2 is observing a different one.

My goal is to call the onChanged of Fragment 2 when onChanged of Fragment 1 is called.

A stupid and naive solution that worked was to set up the observer of Fragment 1 in Fragment 2 and inside it call another observer:

mFragment1ViewModel1.getData().observe(this, new Observer<Fragment1Data>() {
    @Override
    public void onChanged(Fragment1Data fragment1Data) {
        if(fragment1Data != null){
            mFragmentViewModel2.getData().observe(SomeClass.this, new Observer<Fragment2Data>() {
                @Override
                public void onChanged(@Nullable Fragment2Data fragment2Data) {
                    // Do some stuff...
                }
            });
        }
    }
});

Could someone tell me what would be a good solution in this case and the implications of the solution mentioned above?

Suleyman
  • 2,765
  • 2
  • 18
  • 31
  • Dude, no, use MediatorLiveData, see https://stackoverflow.com/a/54292960/2413303 – EpicPandaForce Jun 09 '19 at 23:11
  • @EpicPandaForce I know, it's a horrible solution :D. I tried implementing MediatorLiveData very quickly but didn't see it through. Thanks a lot for the link. So essentially I'll just add **Fragment 1** LiveData as a source and then go from there? – Suleyman Jun 09 '19 at 23:52
  • @EpicPandaForce Could you tell me one last thing, would I have to use Transformations.switchMap? – Suleyman Jun 10 '19 at 23:06
  • uh. depends on how you're trying to chain the LiveData into another LiveData (or not) – EpicPandaForce Jun 10 '19 at 23:17
  • @EpicPandaForce I'll try to explain, I hope it's not over confusing. All I need from **LiveData 1** is to tell me when it's onChanged method has been triggered, then I want to execute the onChanged of **LiveData 2**. I've tried implementing MediatorLiveData just now, I add both sources, but when adding **LiveData 1** source I don't have access to the **LiveData 2**. So I see in **Fragment 2** that it recognizes when LiveData in **Fragment 1** has been triggered, but I cannot do anything about it, since I don't have the relevant data. – Suleyman Jun 10 '19 at 23:32
  • `LiveData 1 is to tell me when it's onChanged method has been triggered, then I want to execute the onChanged of LiveData 2.` that actually sounds like it's just `Transformations.switchMap(liveData1, (x) -> { return liveData2; }).observe(...` – EpicPandaForce Jun 10 '19 at 23:57
  • @EpicPandaForce ,I'll try implementing it, looks like it'll work judging from my little research. Thanks a lot for your time and patience! :) – Suleyman Jun 11 '19 at 07:45
  • 1
    @EpicPandaForce it worked! Thank you very much! Would you want to write an answer so I can accept and upvote it? – Suleyman Jun 12 '19 at 20:00
  • @EpicPandaForce why is it a bad idea to nest LiveData observers??? – pvs Jul 28 '23 at 05:41
  • 1
    @pvs because for the nested LiveData, the old observers will stick around and you will get multiple calls. Like, each time the outer one changes, the new one would get 2, 3, ... N+1 registrations eventually. SwitchMap specifically implements that instead of nesting, a previous registration is removed and a new registration is added. – EpicPandaForce Jul 28 '23 at 13:45

1 Answers1

4

LiveData 1 is to tell me when it's onChanged method has been triggered, then I want to execute the onChanged of LiveData 2

That actually sounds like it's just

Transformations.switchMap(liveData1, (x) -> { return liveData2; })
                 .observe(...
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428