I am using Room for the database layer in my application and Retrofit for network calls - both in room and retrofit I am using RxJava2 (this is my first project with rxjava so I am still quite newbie in this area). To inject database, api etc. I am using Dagger 2.
I want to make a Network Call and add response from the network to the database. When there is no need for making another network call - I want to fetch data from the database. I am having problem with the use of Maybe / Flowable in my room repository.
This is Dao:
@Dao
public interface CoinDao {
@Query("SELECT * FROM coin")
Flowable<List<Coin>> getAllCoins();
@Insert
void insert(List<Coin> coins);
@Update
void update(Coin... coins);
@Delete
void delete(Coin... coins);
}
This is my repository:
public class CoinRepository implements Repository {
private CoinMarketCapNetworkApi api;
private final CoinDao coinDao;
public CoinRepository(CoinMarketCapNetworkApi api, CoinDao coinDao) {
System.out.println("Creating CoinRepository");
this.api = api;
this.coinDao = coinDao;
}
@Override
public Flowable<List<Coin>> getCoinResults() {
System.out.println("getting coin results");
return getCoinResultsFromDatabase().switchIfEmpty(getCoinResultsFromNetwork())
}
@Override
public Flowable<List<Coin>> getCoinResultsFromNetwork() {
System.out.println("getting results from network");
return api.getCoins().doOnNext(new Consumer<List<Coin>>() {
@Override
public void accept(List<Coin> coins) throws Exception {
System.out.println("inserting to db");
coinDao.insert(coins);
}
});
}
@Override
public Flowable<List<Coin>> getCoinResultsFromDatabase() {
System.out.println("getting coins from database");
return coinDao.getAllCoins();
}
}
I firstly run the app to fill the database only with network call
@Override
public Flowable<List<Coin>> getCoinResults() {
return getCoinResultsFromNetwork();
}
And when the network call was executed the data was successfuly added to the database - I run the app once again with only getting data from database and it was also successfull - the data was fetched from db.
@Override
public Flowable<List<Coin>> getCoinResults() {
return getCoinResultsFromDatabase();
}
However when I try now to do such a thing
return getCoinResultsFromDatabase.switchIfEmpty(getCoinResultsFromMemory));
The problem is that everytime switchIfEmpty is executed and every time "getCoinResultsFromMemory()" is executed (even though the data in database is available).
According to https://medium.com/google-developers/room-rxjava-acb0cd4f3757 I have read that the Flowable when there is no data in database will emit nothing and I should use Maybe. But why getResultsFromMemory() returns empty even though there is data in database? How exactly should I use Maybe in this scenario?
I have tried changing Flowable to Maybe
Maybe<List<Coin>> getCoinResultsFromDatabase()
and doing something like this - to access the resutl from maybe and check there if the list is empty or not, but I don't know how to return flowable in this case:
public Flowable<List<Coin>> getCoinResults() {
getCoinResultsFromDatabase().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<Coin>>() {
@Override
public void accept(List<Coin> coins) throws Exception {
System.out.println("returning coins from maybe" + coins.get(0).getId());
if (coins.isEmpty()) {
System.out.println("coin list is empty");
Flowable<List<Coin>> flowable = getCoinResultsFromNetwork();
} else {
Flowable<List<Coin>> flowable = getCoinResultsFromDatabase();
}
}
});
return flowable //how to access this flowable??
}
Maybe I am missing something and there is a better and more clean solution.