Deepak Senapati
Deepak Senapati

Reputation: 1123

Optimal way of creating and handling multiple observables for multiple network calls using RxJava

I need to iterate through a list of data, get all their Ids, trigger network calls using those Ids, and then do something once I get the list of results (The server could take list of Ids and return a list of result but it doesn't work that way as of now).

Currently I got it working like this:

for (Data data: dataList) {
    String id = data.getId();
    idObservables.add(dataService.getResultFromNetwork(id));
}

Observable.zip(idObservables, new FuncN<List<Result>>() {
    @Override
    public List<Result> call(Object... args) {
        List<Result> resultList = new ArrayList<>();
        for (Object arg : args) {
            resultList.add((Result) arg));
        }
        return resultList;
    }
}).subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Action1<List<Result>>() {
        @Override
        public void call(List<Result> resultList) {
           // Do something with the list of Result
        }
    }, new Action1<Throwable>() {
        @Override
        public void call(Throwable throwable) {
            Log.e("", "error", throwable);
        }
    });

But obviously I'm not happy with the way it's done. It will be great to know better ways to handle a case like this using RxJava in Android.

Cheers!!

Upvotes: 0

Views: 49

Answers (1)

Tassos Bassoukos
Tassos Bassoukos

Reputation: 16142

Apologies for the lambda-isms, but it really makes the logic easier to read:

Observable
.fromIterable(dataList)
.flatMap(data -> 
     dataService
     .getResultFromNetwork(data.getId())
     .subscribeOn(Schedulers.io())
)
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(list -> {
    // do something
});

The idea is to keep as much as the pipeline in Rx-land; it's worth it to have simple methods taking normal parameters and return observables, and complex methods take observables and return observables.

Note: the above will not retain ordering; if you need an ordered list, use concatMap with prefetch.

Upvotes: 2

Related Questions