Android Combine 2 Lists of data one from Room LiveData and 1 from Observable

The name of the pictureThe name of the pictureThe name of the pictureClash 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();





Could you share the relevant code?
– Anatolii
Aug 9 at 11:09





@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.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS