rafaelasguerra
rafaelasguerra

Reputation: 2555

Rxjava - isolation of logic

Basically , I want to check if i have data in my DB, and if i dont have, make an api call. I'm using this logic for making the request to the API:

 private void requestDataToApi() {
        mSubscribe = createRequest()
                .delay(DELAY_SPLASH_SCREEN_SECONDS, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(categoryModels -> {
                    writeDataToDb(categoryModels);

                }, (throwable -> {
                    dealError();
                }));
    }

And this logic to verify if there any data stored:

if (mRealm.where(CategoryModel.class).findAll().size() == 0) {
      requestDataToApi();
    } else {
      getView().openMainActivity(readDataFromDb());
    }

There is any way to join this both logics? Basically, be the dispose verifying the db and just make the call if needed?

Upvotes: 2

Views: 147

Answers (3)

Alberto S.
Alberto S.

Reputation: 7649

Looks like you need the Repository Pattern

What this pattern does it isolate the business logic from the data origin. So you just ask for data and don'r care where this data come from. So you could hava something like:

public class CategoryModelRepo {

    public Observable<CategoryModel> getAll() {
        return Observable.defer(() -> {
            List<CategoryModel> fromRealm = mRealm.where(CategoryModel.class).findAll();
            if (fromRealm.size() == 0) {
                return requestDataToApi()
                    .onNext(dataList -> storeDataInRealm(dataList))
            } else {
                return Observable.just(fromRealm);
            }
        }
    }

    // This code fragment could be improved by applying a DAO pattern
    // http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
    private Observable<CategoryModel> requestDataToApi() {
        return createRequest()
            .delay(DELAY_SPLASH_SCREEN_SECONDS, TimeUnit.SECONDS)
    }

So from your business layer (or, in your case, view layer) you can load the data to ensure it has been stored locally.

Don't forget to use .subscribeOn(...) and .observeOn(...) where necessary

Upvotes: 1

paul
paul

Reputation: 13481

You can use filter and switchIfEmpty operator

@Test
public void ifEmpty() throws InterruptedException {
    Observable.just(getDataFromDatabase())
            .filter(value -> !value.isEmpty())
            .switchIfEmpty(Observable.just("No data in database so I go shopping"))
            .subscribe(System.out::println);
}

private String getDataFromDatabase() {
    if(new Random().nextBoolean()){
        return "data";
    }
    return "";
}

You can learn more from reactive world here https://github.com/politrons/reactive

Upvotes: 3

mcassiano
mcassiano

Reputation: 315

If you are willing to add one more dependency to your project, Store is a (very) nice solution. Otherwise, I would recommend using concepts from the Repository pattern.

Upvotes: 0

Related Questions