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
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;
}
}
}