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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With