Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava - Combining multiple/different web service calls

I'm working with the Basecamp api to return and display to do lists. Here's a sample of what I'm doing at the moment:

bcxClient
  .fetchToDoLists()
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Action1<List<BcxToDoList>>() {
    @Override
    public void call(List<BcxToDoList> bcxToDoLists) {

      for( final BcxToDoList toDoList : bcxToDoLists ) {
        bcxClient
          .fetchToDos( toDoList.bucket.id )
          .subscribeOn( Schedulers.io() )
          .observeOn( AndroidSchedulers.mainThread() )
          .subscribe( new Action1<List<BcxToDo>>() {
            @Override
            public void call(List<BcxToDo> bcxToDos) {
              for( BcxToDo toDo : bcxToDos ) {
                toDoList.toDos.add( toDo );
              }
            }
          }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
              throwable.printStackTrace();
            }
          });
      }

      mLoremTextView.setText(bcxToDoLists.get(0).name);
    }

  }, new Action1<Throwable>() {
    @Override
    public void call(Throwable throwable) {
      throwable.printStackTrace();
    }
  });

fetchToDoLists and fetchToDos are Retrofit web service calls that return the BcxToDoList and BcxToDos Observables.

In the subscription to fetchToDoLists I loop through each BcxToDoList, call fetchToDos and attach my BcxToDo objects to the original list.

As you can see, it's a little verbose. I could just separate this into two statements to make it a little bit more readable. But, that's not very Rx. Is there a different way to do this in RxJava and improve its readability?

I could use lambdas to make this compact, but at this stage I'm more interested in what features in RxJava I could take advantage of.

like image 595
Mitkins Avatar asked Aug 04 '26 12:08

Mitkins


1 Answers

You should not "break the chain" in your RxJava calls, hence you will need flatMap to chain them. Also Observable.from() lets you split List of elements into separate Observables. Next, you can use toList to get elements back into list. Here's an example :

bcxClient
        .fetchToDoLists()
        .flatMap(new Func1<List<BcxToDoList>, Observable<BcxToDoList>>() {
            @Override
            public Observable<BcxToDoList> call(List<BcxToDoList> bcxToDoLists) {
                return Observable.from(bcxToDoLists);
            }
        })
        .flatMap(new Func1<BcxToDoList, Observable<List<BcxToDo>>>() {
            @Override
            public Observable<List<BcxToDo>> call(BcxToDoList bcxToDoList) {
                return bcxClient
                        .fetchToDos(bcxToDoList.bucket.id);
                        .map(new Func1<List<BcxToDo>, BcxToDoList>() {
                            @Override
                            public BcxToDoList call(List<BcxToDo> bcxToDos) {
                                bcxToDoList.toDos.addAll(bcxToDos);
                                return bcxToDoList;
                            }
                        });
            }
        })
        .toList()
        .subscribe(...);
like image 109
krp Avatar answered Aug 06 '26 03:08

krp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!