0

I hava a function which is returning an object containing a list from a html page :

@Override
public Observable<MediaList> getMediaListFromUrl(String url) {
    return getHtml(url)
            .map(new Func1<String, MediaList>() {
                @Override
                public MediaList call(String s) {
                    return interpreter.interpretMediaResultsFromHtml(s);
                }
            });
}

What I would like to do next is:

for(Media media : mediaList.getMedias()) {
    if (media.getImageUrl().contains("couvertureAjax")) {
        // fetch media.getImageUrl
        // replace the image url with the result
    }
}

and at the end, return the original MediaList object with the replaced image urls. I think I should use flatmap and from somewhere, but I don't know exactly how.

MediaList.java:

import android.os.Parcel;
import android.os.Parcelable;

import java.util.List;

public class MediaList implements Parcelable {
    public static final String TAG = MediaList.class.getSimpleName();
    private List<Media> medias;
    private String nextPageUrl;

    public MediaList() {}

    protected MediaList(Parcel in) {
        medias = in.createTypedArrayList(Media.CREATOR);
        nextPageUrl = in.readString();
    }

    public List<Media> getMedias() {
        return medias;
    }

    public void setMedias(List<Media> medias) {
        this.medias = medias;
    }

    public String getNextPageUrl() {
        return nextPageUrl;
    }

    public void setNextPageUrl(String nextPageUrl) {
        this.nextPageUrl = nextPageUrl;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeTypedList(medias);
        dest.writeString(nextPageUrl);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<MediaList> CREATOR = new Creator<MediaList>() {
        @Override
        public MediaList createFromParcel(Parcel in) {
            return new MediaList(in);
        }

        @Override
        public MediaList[] newArray(int size) {
            return new MediaList[size];
        }
    };
}
Nicolas
  • 598
  • 3
  • 15

2 Answers2

1

As I am not having all classes that are involved here, so I have written a Rx code that would help to achieve what you want:

getHtml(url)
                .flatMap(new Func1<String, Media>() {
                    @Override
                    public Media call(String s) {
                        // Here update code interpreter.interpretMediaResultsFromHtml(s) and make sure your return List<Media> from here
                        return Observable.from(interpreter.interpretMediaResultsFromHtml(s));
                    }
                })
                .map(new Func1<Media, Media>() {
                    @Override
                    public Media call(Media media) {
                        // Write code here to update Url in media and return it
                        return null; // Return updated media object from here
                    }
                })
                .toList()
                .subscribe(new Action1<List<Media>>() {
                    @Override
                    public void call(List<Media> mediaList) {
                        // Here MediaLkist object will be your updated List<Media>
                    }
                });

Let me know if it fix your issue or you need more details. It's definitely possible what you want to achieve via RxJava.

Sagar Trehan
  • 2,401
  • 2
  • 24
  • 32
  • It's a good start. But what I want at the end is realy the MediaList object consisting of a List and nextPageUrl. But maybe my architecture should be changed. – Nicolas Apr 10 '16 at 07:52
0

One way to do this :

@Override
public Observable<MediaList> getMediaList(String url) {
    return getHtml(url)
            .flatMap(new Func1<String, Observable<MediaList>>() {
                @Override
                public Observable<MediaList> call(String s) {
                    MediaList mediaList = interpreter.interpretMediaResultsFromHtml(s);
                    Observable<List<Media>> list = Observable.from(mediaList.getMedias())
                            .flatMap(new Func1<Media, Observable<Media>>() {
                                @Override
                                public Observable<Media> call(Media media) {
                                    if (media.needImagePreload()) {
                                        return getMediaLoadedImage(media.getImageUrl(), media);
                                    } else {
                                        return Observable.just(media);
                                    }
                                }
                            })
                            .toList();
                    return Observable.zip(Observable.just(mediaList.getNextPageUrl()), list, new Func2<String, List<Media>, MediaList>() {
                        @Override
                        public MediaList call(String s, List<Media> medias) {
                            return zipMediaList(s, medias);
                        }
                    });
                }
            });
}


private MediaList zipMediaList(String s, List<Media> medias) {
    MediaList mediaList = DefaultFactory.MediaList.constructDefaultInstance();
    mediaList.setNextPageUrl(s);
    mediaList.setMedias(medias);
    return mediaList;
}

I think they are easier ways to do this, but it works.

Nicolas
  • 598
  • 3
  • 15