Search code examples
androidjava-streamrx-javarx-android

RxJava transform request type before api call


I have a list of Users (imagine POJO User has Id as int and Name as string), and I want to make an API call passing as parameter the list of IDs instead the list of Users. So, as I have it is:

    List<Integer> usersIDs = new ArrayList<>();
    usersList.stream().forEach(user -> users.add(users.getId()));

    Single.fromCallable(() -> api.downloadData())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe();

but I'd like to transform this list in the RxJava call itself, inside the chain with an operator like when we use it to transform, map, filter, whatever, the result list.

Is there a way? thanks


Solution

  • What about this?

    You can use Observable#fromIterable in order transform from User to Integer (id). This is done via applying toList. This can only be done on a finite stream, because you will never get a emit, when the Observable never send a onComplete. In your case it is possible, because a List is always finite.

    class So65424108 {
      @Test
      void so65424108() {
        List<User> users = Arrays.asList(new User(1, "Hans"), new User(2, "Wurst"));
    
        Api api = new ApiImplStub();
        TestScheduler testScheduler = new TestScheduler();
    
        ReactiveApi reactiveApi = new ReactiveApi(api, testScheduler);
    
        TestObserver<Boolean> test = Observable.fromIterable(users)
            .map(user -> user.userId)
            .toList()
            .flatMap(reactiveApi::downloadData)
            .observeOn(testScheduler)
            .test();
    
        testScheduler.triggerActions();
    
        test.assertComplete().assertValue(false);
      }
    
      interface Api {
        Boolean downloadData(List<Integer> ids);
      }
    
      static final class ApiImplStub implements Api {
        @Override
        public Boolean downloadData(List<Integer> ids) {
          return false;
        }
      }
    
      static final class ReactiveApi {
        private final  Api api;
        private final Scheduler scheduler;
    
        ReactiveApi(Api api, Scheduler scheduler) {
          this.api = api;
          this.scheduler = scheduler;
        }
    
        public Single<Boolean> downloadData(List<Integer> ids) {
          return Single.fromCallable(() -> api.downloadData(ids))
              .subscribeOn(scheduler);
        }
      }
    
      static final class User {
        final int userId;
        final String name;
    
        User(int userId, String name) {
          this.userId = userId;
          this.name = name;
        }
      }
    }