Reputation: 3813
Within my Activity I am firing an HTTP Request with Retrofit2
. On success I receive an array of elements. On every element I fire a second request which again responses with an array of elements on success. I need an event to trigger as soon as all nested requests are finished. How can I achieve that without counting the successes of every nested request and comparing it to the size of the first array? Here is my Activity
:
public class ABCActivity extends AppCompatActivity {
private static final String TAG = "StackoverflowActivity";
private Disposable mDmRequestSubscription;
private StopRequestApiInteractor mStopRequestInteractor;
private DmRequestApi mDmRequestApiInteractor;
private Position mPosition;
private List<ItdOdvAssignedStop> mStopsList = new ArrayList<>();
private List<List<ItdDeparture>> mAllDepartures;
private List<Place> mStopsInRange = new ArrayList<>();
private List<Place> stopsInRange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestStops();
}
public void requestStops() {
mStopRequestInteractor
.getStopFinderRespond(mPosition)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(s -> Observable.just(s.getStopFinder().getItdOdvAssignedStops()))
.subscribe(this::onSuccess, this::onError);
}
private void onError(Throwable throwable) {
throwable.printStackTrace();
}
private void onSuccess(ItdOdvAssignedStop[] response) {
mStopsList.clear();
mStopsList.addAll(Arrays.asList(response));
for (ItdOdvAssignedStop stop : mStopsList) {
mDmRequestSubscription = mDmRequestApiInteractor
.getStopDmRespond(stop.getStopID())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onDmRequestSuccess, this::onDmRequestError);
}
}
private void onDmRequestError(Throwable throwable) {
Log.e(TAG, "DM Request failed");
}
private void onDmRequestSuccess(ResponseBody entry) {
Log.d(TAG, "DM Request success");
mStopsInRange = getStopsInRange();
update();
}
public List<Place> getStopsInRange() {
//Some things done here...
return stopsInRange;
}
private void update() {
//Shall be called only once as soon as all onDmRequestSuccess() were fired
}
}
My Activity is not runnable outside of my project. I just want a clean solution to trigger update()
only once as soon as all requests are responded. And not every time a nested request is responded.
How can I implement that using onNext()
, onCompleted()
and onError()
methods of Subscriber
? So how to transform my code into something like the following?
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Test");
subscriber.onError(null);
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onNext(String s) {
System.out.println("onNext");
}
});
Upvotes: 0
Views: 758
Reputation: 2487
You can accomplish this using 2 flatMaps. The trigger you are looking for is the onComplete call itself, as all streams will either terminate normally or with an exception which will be propagated into onError method.
Conceptually, you are looking for something like this:
getMainRequest()
.flatMap(itemList -> Observable.from(itemList))
.flatMap(item -> secondRequest(item))
.subscribe(result -> {
}, error -> {
// some stream encountered an error
}, () -> {
// all requests have finished
})
Upvotes: 2