0

Hello Everyone and Hello Everything !

I have two independent api (lastFM and iTune) source. Code is working for ich separately, and I can search (filter) for artist that I want. Now I want to combine results, using for this RXJava approach and show them in RecyclerView.

I was reading about Observable.zip or simple merge (the order is not important) but I stuck on this problem too long and I don't knew how to start .. should I create next model for combine like :

public class iTuneAndLastFM {

    public JsonArray iTuneObject;
    public JsonArray LastFmObject;

    public iTuneAndLastFM(JsonArray iTuneObject, JsonArray lastFmObject) {
        this.iTuneObject = iTuneObject;
        LastFmObject = lastFmObject;
    }
}

or there is no need ? I stuck here and I cannot move .. so pleace help !

my current work (situation):

public interface ServiceItune

String API_ITUNE_BASE_FULL_URL = "https://itunes.apple.com/search";
        @GET
        Observable<RootiTune> getItuneArtistNameRx2NoList(
                @Url String url,
                @Query("term") String artisName);

public interface ServiceLastFm

String API_LAST_FM_FULL_URL = "http://ws.audioscrobbler.com/2.0/?method=artist.search&format=json";

    Observable<RootLastFm> searchArtistRx(
            @Url String url,
            @Query("artist") String artistName,
            @Query("api_key") String key
    );

my ViewModel:

public void getLastFmRx(String query) {
    disposables.add(serviceLastFm.searchArtistRx(ServiceLastFm.API_LAST_FM_FULL_URL, query,ServiceLastFm.KEY_LAST_FM)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(rootLastFmList -> responseLiveData.setValue(rootLastFmList))
            );
};
public  void getItubnRxTest2 (String query){
    disposables.add(serviceItune.getItuneArtistNameRx2NoList(ServiceItune.API_ITUNE_BASE_FULL_URL,query)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(rootiTuneList->responsItuneeLiveData.setValue(rootiTuneList) )
    );
};

and last, my iTunes model:

@AutoValue
public abstract class  RootiTune {

    public static TypeAdapter<RootiTune> typeAdapter(Gson gson){
        return new AutoValue_RootiTune.GsonTypeAdapter(gson);
    }
    @Nullable
    @SerializedName("resultCount")
    public abstract Integer getListSize();

    @Nullable
    @SerializedName("results")
    public abstract List<ResultiTune> getListSongs();

    @Nullable
    @SerializedName("errorMessage")
    public abstract String getErrorMessage();

}

and LastFM model:

public class RootLastFm {
    @Expose
    private Results results;
    public List<ArtistLastFm> getListOfLastFm;
    public Results getResults() {
        return results;
    }
    public void setResults(Results results) {
        this.results = results;
    }
}
htw
  • 1,065
  • 7
  • 11

2 Answers2

0

If you don't have basic interface for RootiTune and RootLastFm, you can use Observable#zip(). First of all, create wrapper for two results:

class ResultWrapper(RootiTune ituneResult, RootLastFm lastFmResult) {
    public final RootiTune ituneResult;
    public final RootLastFm lastFmResult;

    public ResultWrapper(RootiTune ituneResult, RootLastFm lastFmResult) {
        this.ituneResult = ituneResult;
        this.lastFmResult = lastFmResult;
    }
}

After that you can zip sources:

Observable<RootiTune> ituneObservable = serviceItune.getItuneArtistNameRx2NoList(ServiceItune.API_ITUNE_BASE_FULL_URL,query);
Observable<RootLastFm> lastFmObservable = serviceLastFm.searchArtistRx(ServiceLastFm.API_LAST_FM_FULL_URL, query,ServiceLastFm.KEY_LAST_FM);
Observable.zip(ituneObservable, lastFmObservable, (ituneResult, lastFmResult) -> new ResultWrapper(ituneResult, lastFmResult))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(resultWrapper -> {
            responseFmLiveData.setValue(resultWrapper.lastFmResult);
            responsItuneeLiveData.setValue(resultWrapper.ituneResult);
        }, 
        error -> {
            // TODO handle error
        });
ConstOrVar
  • 2,025
  • 1
  • 11
  • 14
0

You can do something like this,

Observable<RootiTune> ituneObservable = serviceItune
        .getItuneArtistNameRx2NoList(ServiceItune.API_ITUNE_BASE_FULL_URL, query);
Observable<RootLastFm> lastFmObservable = serviceLastFm
        .searchArtistRx(ServiceLastFm.API_LAST_FM_FULL_URL, query, ServiceLastFm.KEY_LAST_FM);
Observable
    .zip(
        ituneObservable,
        lastFmObservable,
        (BiFunction<RootiTune, RootLastFm, Pair<RootiTune, RootLastFm>>) (ituneResult, lastFmResult) -> Pair
             .create(ituneResult, lastFmResult)
        )
        .toList()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            list -> listOfPair,
            error -> {
                // TODO handle error
            }
        );

Once you get list of Pair, loop through list and do

pair.first to get RootiTune
pair.second to get RootLastFm
arungiri_10
  • 988
  • 1
  • 11
  • 23