How to repeat network calls using RxJava
I have an API that lets me retrieve items using an id like this:
http://myapi.com/api/v1/item/1
The last of these values is the ID of the item. That’s fine, dude, I can write a Retrofit service interface and call the project like this:
MyService service = MyService.retrofit.create(MyService.class);
service.itemById(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<Item>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.v(LOG_TAG, e.getMessage());
}
@Override
public void onNext(Item item) {
adapter.addItem(item);
}
});
The problem I’m having is that I want to retrieve 5 items at once, but I don’t know how to do it. For example, if I want to get items with IDs 1, 2, 3, 4, 5, how can I do this in a group? I looked at Observable.zip()
but I’m not quite sure how to set it up.
Solution
If you want
to use zip, you’ll want to do something like this (use lambda syntax for brevity):
Observable.zip(
service.itemById(1),
service.itemById(2),
service.itemById(3),
service.itemById(4),
service.itemById(5),
(i1, i2, i3, i4, i5) -> new Tuple<>(i1, i2, i3, i4, i5))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(
tuple -> {
< use the tuple >
},
error -> {
// ...
}
);
Note: You must either create a Tuple class or some other object, or import a Tuple library.
Another variant based on your review:
Observable.range(1, 5)
.flatMap(t -> service.itemById(t), (i, response) -> new Tuple<>(i, response))
.subscribeOn(Schedulers.io())
.subscribe...
This will run your request in parallel, and your subscription block will receive each element separately.
Observable.range(1, 5)
.flatMap(t -> service.itemById(t), (i, response) -> new Tuple<>(i, response))
.collect(ArrayList::new, ArrayList::add)
.subscribeOn(Schedulers.io())
.subscribe...
This collects the resulting tuples into an array.