airbnb / mavericks

Mavericks: Android on Autopilot
https://airbnb.io/mavericks/
Apache License 2.0
5.83k stars 500 forks source link

Multiple states/passing data from one viewmodel to another? Very specific problem #174

Closed bernaferrari closed 5 years ago

bernaferrari commented 5 years ago

Hi! I'm currently redesigning this project following MvRx principles and it is going well.. mostly. My issue is the following:

I have a fragment with a fragment inside it, one with horizontal scroll, the other with a vertical one. There is one entry of data, and I have the same list (~300 elements) on both recyclerviews. One of them renders gifs, the other is a menu to help the user search/filter between them. After getting data from server, I want to show it fully on the main list, while it might be filtered on the second list. For the second list, I usually use a RxRelay and every letter the user puts goes together with a CombineLatest to generate a new Epoxy list, similar to this other app. The problem is that I can't just call 'execute' for two different things, I would need two states/two executes to do what I want, out of the same observable. Since it has one point of entry and similar data, it also doesn't makes sense to call the server twice.

I thought about fetching in one ViewModel and calling the execute() on a secondary viewmodel with the list returned from the first one - not an elegant solution, but might work. I also thought about the possibility of multiple states on the same viewmodel, but I didn't find anything on documentation beyond setState. Any ideas? Is there a 'recommended' way of doing what I want? Has someone on Airbnb ever had a similar problem?

manueldidonna commented 5 years ago

If I understood the problem, you could share the same viewmodel between the fragments. Create a state with a list and a filteredList. On execute set both variables with data received from server. Within your child fragment (vertical scroll) just modify state::filteredList

bernaferrari commented 5 years ago

It makes sense. One question: when the filter is updated (i.e. the user typed anything), will it update the first recyclerview or the diff from epoxy will prevent it from modifying anything (since nothing really changed) and will only change the second one?

manueldidonna commented 5 years ago

Using two different list any changes committed in the child fragment won't update the main fragment

gpeal commented 5 years ago

@bernaferrari epoxy does model diffing. If you return the same values again, nothing will re-render.

bernaferrari commented 5 years ago

Thanks for all! I'm traveling, I'll test when I come back. Loving MvRx!!