Home » Android » android – RxJava – Chaining requests and updating UI

android – RxJava – Chaining requests and updating UI

Posted by: admin June 15, 2020 Leave a comment

Questions:

The problem I’m having is this. I need to execute couple of requests to the server. Each next request depends on the result of previous one.
They look like this (abbreviated):

Observable<FileUploadResponse> obsFile = api.uploadFile();
Observable<TokenCreateResponse> obsCreateToken = api.createToken();
Observable<PaymentResponse> obsPayment = api.submitOrder();

I’ve created a single observable using a flatMap which returns the PaymentResponse object or emits onError() if some of the requirements aren’t met. This is working fine and I get all the requests done in a single call.

The problem is I can’t update the UI between these requests. With current setup, I show the loading when request starts and hide it when all the requests are complete. Is there a way to update the UI in-between these requests?

What I want is this:
1. File uploading – write a message on the UI.
2. Creating a token – write a message on the UI.
3. Submitting order – write a message on the UI.
4. Once all are complete, hide the progress dialog.

My understanding would be to emit some Observable using onNext() when each API call is finished and then calling onComplete() when all are done. But how do I do this?

How to&Answers:

You could achieve this with doOnNext and a PublishSubject. First create a subject and some values:

public static final int STATUS_UPLOADING = 0;
public static final int STATUS_TOKEN = 1;
public static final int STATUS_SUBMITTING = 2;
public static final int STATUS_DONE = 3;

PublishSubject<Integer> status = PublishSubject.create();

public Observable<Integer> getStatusStream() {
    return status;
}

Then when you’re doing your upload work just send the value to the subject each time:

status.onNext(STATUS_UPLOADING);

return api.uploadFile()
    .doOnNext(o -> status.onNext(STATUS_TOKEN))
    .flatMap(o -> api.createToken())
    .doOnNext(o -> status.onNext(STATUS_SUBMITTING))
    .flatMap(o -> api.submitOrder())
    .doOnNext(o -> status.onNext(STATUS_DONE))

Then you can subscribe to the Subject and update your UI:

model.getStatusStream()
    .subscribeOn(AndroidSchedulers.mainThread())
    .subscribe(
        status -> {
            view().setMessage(status);
        },
        Throwable.printStackTrace
    );

Alternatively depending on how you want to architect your app you could just call the update view calls from doOnNext each time. You’d probably need to use observeOn to switch between the main & background thread each time.