Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining API calls with RX Java

I'm new to RXJava and i'm having trouble understanding how to chain together the result of API calls.

I'm making two API calls using retrofit, A and B, which both return an observable List of objects. Both API calls are independent so I want to make both at the same time, but to achieve my final result, I need to first take the result of A, do some work, then combine that with the result of B to populate my list adapter.

  • Make API Call A
  • Make API Call B
  • Take A's result and create result X
  • Take Result of B + X and populate adapter

    @GET("/{object_id}/object_a")
        Observable<List<Object_A>> getObjectAList(
            @Path("object_id") long object_id);
    
    
    @GET("/{object_id}/object_b")
        Observable<List<Object_B>> getObjectBList(
            @Path("object_id") long object_id);
    

This is where I get lost trying to use RX java. I can take the result of api call A and do my work but I'm not sure how to take the result I just generated and combine it with API Call B.

aService. getObjectAList(object_a.getID())
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(AndroidSchedulers.main)
            .subscribe(new Action1<List<Object_A>>() {

                @Override
                public void call(List<Section> sections) {
                    // Do Stuff Here...
                    // Now i need to take this result and combine it with API Call B...
                }
            });

I want to make both API calls at the same time, but i'm not sure how to chain together and combine API calls. Any help is appreciative.

like image 443
user3169791 Avatar asked Nov 10 '14 15:11

user3169791


People also ask

How does RxJava chain work?

It changes the thread as many times as you write it. flatMap starts the chain only during root chain data emission. No actions are performed during the root stream subscription process. Operators interval/delay/timer subscribe to computation under the hood, by default.


2 Answers

Something like this?

Observable
        // make api call for A list and B list
        .combineLatest(getObjectAList(), getObjectBList(), new Func2<List<Object_A>, List<Object_B>, Object>() {
            @Override
            public Object call(List<Object_A> o, List<Object_B> o2) {
                // Do what you need to do in the background thread
                List x = createX(o);
                List y = createY(x, o2);
                return y;
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<Object>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Object y) {
                // UI thread, do what you need e.g. renders the list
                mAdapter.setList(y);
            }
        });

Taking care of replacing the proper types should bring you quite close to the solution.

like image 140
Ivan Morgillo Avatar answered Oct 15 '22 17:10

Ivan Morgillo


The question is : how would you combine results ?

Building a new result from List and List ? Combine A objects with B objects ?

Answer to this question help to find the right operator for your problem.

A simple example of combining results can be this :

 getObjectAList().zipWith(getObjectBList(), (aList, bList) -> // combine both list to build a new result)).subscribe()

You can combine elements of the list too with another operator (combineLatest for example)

aObs = getObjectAList().flatMap(Observable::from);

bObs = getObjectBList().flatMap(Observable::from);
Observable.combineLatest(aObs, bObs, (a,b) -> // combine a object with b object).subscribe();

For all of this examples above, requests will be done in parallel by retrofit.

like image 2
dwursteisen Avatar answered Oct 15 '22 18:10

dwursteisen