Java – How to repeat network calls using RxJava

How to repeat network calls using RxJava… here is a solution to the problem.

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.

Related Problems and Solutions