Vodet
Vodet

Reputation: 1519

Retrofit 2 and rxJava with Flowable concat handle several response

I'm using retrofit, rxJava and realm I'm using flowable concat for launch a request to the server and another one for realm

This is how I'm creating the disposable :

  disposable.add(launchRequest()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Config>() {
                @Override
                public void accept(Config config) throws Exception {
                    ProfileManager.getInstance().setConfig(config);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(@NonNull Throwable throwable) throws Exception {
                    if (!throwable.getMessage().equals(ErrorUtils.ERROR_CODE_304)) {
                        throwable.printStackTrace();
                    }
                }
            }));

launchRequest function create the Flowable :

Flowable.concat(cloudDataStore.getById(single, diskDataStore, repositoryItem).toFlowable(), diskDataStore.getById(id, repositoryItem).toFlowable())
            .map(new Function<Object, T>() {
                @Override
                public T apply(Object o) throws Exception {
                    return repositoryItem.toView((T) o);
                }
            });

cloudDataStore param is the retrofit part and diskDataStore is the realm part. Everything workings fine here, my trouble is when I handle the retrofit request :

 return single.flatMap(new Function<Response<T1>, SingleSource<T1>>() {
        @Override
        public SingleSource<T1> apply(@NonNull Response<T1> response) throws Exception {
            if (response.code() == Integer.valueOf(ErrorUtils.CODE_200)) {
                return Single.just(response.body());
            } else if (response.code() == Integer.valueOf(ErrorUtils.ERROR_CODE_304)) {
                 return Single.just(response.body());
            } else {
                return Single.error(new Throwable(String.valueOf(response.code())));
            }
        }
    });

If the request is sucessfull (status 200) I return the server response to my disposable.

If I got a code 304 the response body is null so the disposable throwable is trigger, but if the throwable is trigger the disposable don't wait the realm response from concat and stop listening.

The workaround I find is to create a empty Object and return it like this :

if (response.code() == Integer.valueOf(ErrorUtils.ERROR_CODE_304)) {
             return Single.just(new Config());
}

This trigger the disposable consumer with an empty object and I can after get the realm result with the good value because the throwable is not trigger.

But I don't want to receive this empty result I can do nothing with it and I need for all request to check if the content is not null like this :

 .subscribe(new Consumer<Config>() {
            @Override
            public void accept(Config config) throws Exception {
                 if (config.getContent != null){
                      ProfileManager.getInstance().setConfig(config);
                 }        
            }
        }

How can I return something with Single that don't trigger the consumer and the throwable ?

Upvotes: 0

Views: 744

Answers (1)

Vodet
Vodet

Reputation: 1519

Thanks to EpicPandaForce the solution was to change the Single into Maybe like this :

.flatMap(new Function<Response<T>, Maybe<T>>() {
        @Override
        public Maybe<T> apply(@NonNull Response<T> response) throws Exception {
            if (response.code() == Integer.valueOf(ErrorUtils.CODE_200)) {
                return Maybe.just(response.body());
            } else if (response.code() == Integer.valueOf(ErrorUtils.ERROR_CODE_304)) {
                return Maybe.empty();
            } else {
                return Maybe.error(new Throwable(String.valueOf(response.code())));
            }
        }
    });

Upvotes: 1

Related Questions