LittleBooger
LittleBooger

Reputation: 11

RxJava Itereate list in an object and return the object

There is a requirement to do an api request and download all assets returned in response. I have the logic below, but not sure what is the proper way to complete this.

 public Observable<Response> prepareSomething() {
    return api.requestSomthing()
            .observeOn(Schedulers.io())
            .flatMap(response -> Observable.fromIterable(response.getAssetsList()))
            .map(asset -> downloadAsset(asset, response.getSomeValue/*how?*/))
            .someRxOperatorToRetrunResponseObject(/*how?*/);
}

I actually found a way to implement it in the following way:

public Observable<Response> prepareSomething() {
    return api.requestSomthing()
            .observeOn(Schedulers.io())
            .flatMap(response -> {
                ArrayList<Observable<Asset>> observables = new ArrayList<>();
                for(Asset asset : response.getAssetsList()){
                    Observable downloadOb = Observable.just(asset)
                            .map(assetToDownload-> downloadAsset(assetToDownload, response.getSomeValue()));
                    observables.add(downloadOb);
                }

                return Observable.zip(observables, objects -> response);
            });
}

But it just doesn't look quite nice. Appreciate if anyone can help to inprove this.

Upvotes: 0

Views: 48

Answers (1)

Tuby
Tuby

Reputation: 3253

I would nest downloading logic into inner Observable

public Observable<Response> prepareSomething() {
        return api.requestSomthing()
                .observeOn(Schedulers.io())
                .flatMap(response -> Observable.fromIterable(response.getAssetsList())
                        .flatMap( asset -> downloadAsset(asset))
                        .toList()
                        .flatMapObservable(downloadedAssets -> Observable.just(response))
                );
    }

You get access to response and downloaded assets in the same lambda

Upvotes: 1

Related Questions