Reputation: 841
I am learning to use RxJava with Android. In my project, I have a single situation where I get a List
of items from the server, and I need to get the details of each item, before returning the response to the UI.
The problem is: I am not sure how to sync
the API calls that are called inside the for loop
. I want the end result returned to the UI only after all calls in the foor loop
complete.
Any hints are highly appreciated.
Sample code:
Observable<List<Favorite>> result = ApiWrapper.getFavorites(userData)
.flatMap(new Func1<List<Favorite>, Observable<List<Favorite>>>() {
@Override
public Observable<List<Favorite>> call(@NonNull final List<Favorite> response) {
for(int i = 0; i < response.size(); i++){
getDetailsForFavoriteItem(response.get(i));
}
return Observable.just(response);
}
});
private Observable<Favorite> getDetailsForFavoriteItem (Favorite item){
return ApiWrapper.getDetails(item.getId())
.flatMap(new Func1<FavoriteDetailsResponse, Observable<Favorite>>() {
@Override
public Observable<Favorite> call(@NonNull final FavoriteDetailsResponse response) {
item.setParam1(response.getParam1());
item.setParam2(response.getParam2);
//so on
return Observable.just(item)//!!!issue is here ! I want this return to be called only after all the details (in the for loop) have been called
}
});
}
Upvotes: 1
Views: 2512
Reputation: 6829
First of all, your API in getDetailsForFavoriteItem()
is not called because you are not subscribing to an Observable
.
Second, it would be better to flatMap
your first response into one Observable<Favorite>
and then flatMap
it again to get a details for it. Something like this:
Observable<List<Favorite>> result = ApiWrapper.getFavorites(userData)
.flatMapIterable(favorites -> favorites)
.flatMap(favorite -> getDetailsForFavoriteItem(favorite))
.toList();
You can even make parallel calls to get your details by:
Observable<List<Favorite>> result = getFavorites()
.flatMapIterable(favorites -> favorites)
.flatMap(favorite -> getDetailsForFavoriteItem(favorite)
.subscribeOn(Schedulers.io()), maxConcurrentCalls) // be sure to limit your maxConcurrentCalls or you might get OOM error
.toList();
Upvotes: 7