AdamMc331
AdamMc331

Reputation: 16691

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.

Upvotes: 3

Views: 847

Answers (2)

Maxim Volgin
Maxim Volgin

Reputation: 4077

Observable<List<YourType>> list = Observable.range(/.../).map(/.../).toList();

Upvotes: 0

drhr
drhr

Reputation: 2281

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.

Upvotes: 5

Related Questions