McAdam331 McAdam331 - 1 month ago 9
Java Question

How to repeat network calls using RxJava

I have an API that lets me retrieve an item by an id using something like this:

http://myapi.com/api/v1/item/1


Where the last value is the id of the item. This is fine and dandy, I can write a Retrofit service interface and call for the item 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 run into is that I want to retrieve 5 items at a time, but I don't know how I can do that. If for example I want to get items with id 1, 2, 3, 4, 5, how can I do this in one group? I've looked into
Observable.zip()
but I can't quite figure out how to set this up.

Answer

If you want to use zip, you'd want to do something like this (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'd have to either create a Tuple class, or some other object, or import a Tuple library.


Another variation based on your comment:

Observable.range(1, 5)
    .flatMap(t -> service.itemById(t), (i, response) -> new Tuple<>(i, response))
    .subscribeOn(Schedulers.io())
    .subscribe...

This will run your requests 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 will collect the resulting tuples in an array.

Comments