Reputation: 1123
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
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