Reputation: 1
I call my API with retrofit/rxJava and I get an Observable response like a Single List of BreedDog
. You can see my code :
compositeDisposable.add(breedDogsDisplayDataRepository.getBreedDogs(name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedDog>>() {
@Override
public void onSuccess(List<BreedDog> breedDogList) {
Log.e("test", "okPresenter");
view.displayBreedDogs(breedDogToViewModelMapper.map(breedDogList));
}
@Override
public void onError(Throwable e) {
Log.e("test", "errorPresenter : " + e.toString());
// handle the error case
System.out.println(e.toString());
}
}));
This works but now, for every items of this list I need to call my API to get an URL image and update my list.. But I don't know how... I tried change my Single response in Observable and used operator like flatMap or flatMapIterate.. etc But all time I got errors with the Object.. like no instance...etc
This is an example :
breedDogsDisplayDataRepository.getBreedDogs(name)
.flatMapIterable(breedDogs -> breedDogs)
.map( item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedImageResponse>>() {
@Override
public void onSuccess(List<BreedImageResponse> breedImageResponses) {
}
@Override
public void onError(Throwable e) {
Log.e("test", "errorPresenter : " + e.toString());
// handle the error case
System.out.println(e.toString());
}
})));
Do I use the good way ? Or need to change something ?
Upvotes: 0
Views: 214
Reputation: 1
This is my solution to solve the problem :
public Single<List<BreedDogWithImage>> searchDogs(String name) {
return getBreedDogs(name)
.flatMapIterable(breedDogs -> breedDogs)
.flatMap(breedDog -> getImageBreedDogs(breedDog.getId())
.flatMapIterable(breedDogWithImages -> breedDogWithImages))
.toList();
}
And so I can call it like this :
public void searchBreedDogs(String name) {
compositeDisposable.clear();
compositeDisposable.add(breedDogsDisplayDataRepository.searchDogs(name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedDogWithImage>>() {
@Override
public void onSuccess(List<BreedDogWithImage> breedDogWithImages) {
Log.e("test", "okCall" + breedDogWithImages);
view.displayBreedDogs(breedDogToViewModelMapper.map(breedDogWithImages));
}
@Override
public void onError(Throwable e) {
Log.e("test", "error ");
e.printStackTrace();
}
}));
}
Upvotes: 0
Reputation: 17095
Without the signature of the repository it's hard to say exactly what's wrong, but you do mention that getBreedDogs
returns a Single<List<BreedDogs>>
. If this is the case, Single
doesn't have a flatMapIterable
as far as I know, but it has flattenAsObservable
which can be used to do what you want I think.
It will map the list inside the single and emit its items as observables. This means you can no longer use map
and have to switch to flatMap
:
.flattenAsObservable(breedDogs -> breedDogs)
.flatMapSingle(item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId()))
flatMapSingle
is used because we're flat mapping Singles
in this case
Another thing I noticed is that your "subscription part" is inside the map
and you want this out of it. so ideally you'd move outside like:
.flattenAsObservable(breedDogs -> breedDogs)
.flatMapSingle(item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId()))
.subscribeWith(/*...*/);
The schedulers is up to you. If you want your images to be downloaded in parallel I'd recommend to keep them inside the flatMapSingle
.
Last thing, it seems that you want to receive a List<BreedImageResponse>
, so I'd use toList()
. Putting everything together:
breedDogsDisplayDataRepository.getBreedDogs(name)
.flattenAsObservable(breedDogs -> breedDogs)
.flatMapSingle(item ->
breedDogsDisplayDataRepository.getImageBreedDog(item.getId())
.subscribeOn(Schedulers.io())
)
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSingleObserver<List<BreedImageResponse>>() {
@Override
public void onSuccess(List<BreedImageResponse> breedImageResponses) {
}
@Override
public void onError(Throwable e) {}
});
Upvotes: 0