Android Combine 2 Lists of data one from Room LiveData and 1 from Observable
Clash Royale CLAN TAG#URR8PPP
Android Combine 2 Lists of data one from Room LiveData and 1 from Observable
I am building an app that for now have one main data model Character
, I'm using Room as local DB and retrofit2 for API calls.
The user can set a Character as favorite and when this happens this character is stored in local DB (only local DB know about favorite characters of a current user, this app does not store any data on remote servers just use API to get a list of characters).
The question is when user load next time the app how to load the list from web and from local DB (Room return LiveData<List<Character>
) and filter out from web list Characters
which stored in local DB with the help of RxJava2 (I can use Observable as return from retrofit2) so when I show the list in RecyclerView there will be no duplicates.
Character
LiveData<List<Character>
Characters
For better understand of what i mean:
I have MainActivity
which have MainViewModel
, in MainViewModel
i have CharacterRepository
reference which know how to load data from web as (Call<CaharacterResponse> / Observable<CharacterResponse>
) and load method from local DB Livedata<List<Character>>
(this is list of Characters which marked as favorite by user).
what i want is when user load the application both the web and the local data will be loaded and then results will be filtered to remove duplicates.
*CharacterResponse have extra fields about web call result and one of the fields is List.
MainActivity
MainViewModel
MainViewModel
CharacterRepository
Call<CaharacterResponse> / Observable<CharacterResponse>
Livedata<List<Character>>
@Dao
public interface CharacterDao
@Query("SELECT * FROM character ORDER BY name")
LiveData<List<Character>> getAllFavoriteCharacters();
....
public interface ExampleClient
String BASE_URL = "http://gateway.example.com/public/";
@GET("characters/id")
Call<CharacterResponse> getCharacter(@Path("id")int id);
@GET("characters")
Call<CharacterResponse> getCharacters(@Query("limit") @Nullable Integer limit);
Observable<CharacterResponse> getCharacters();
@Anatolii i edited the question
– satis
Aug 10 at 11:04
1 Answer
1
In order to handle both LiveData
and Observable
in one way you can adapt them into each other by LiveDataReactiveStreams and Observable.fromPublisher()
.
LiveData
Observable
Observable.fromPublisher()
Then you'll have 2 Observables
which provides data - one from web and other from local DB.
Observables
Observable.concatArrayEager
Or you can merge local with remote
local.mergeWith(remote)
.collect(() -> new HashSet<Integer>(), (set, v) -> set.add(v))
.flatMap(Observable::from)
.subscribe(System.out::println);
local.mergeWith(remote)
.collect(() -> new HashSet<Integer>(), (set, v) -> set.add(v))
.flatMap(Observable::from)
.subscribe(System.out::println);
Or you could use distinct operator to remove duplicates from Observable
Observable
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Could you share the relevant code?
– Anatolii
Aug 9 at 11:09