Rxjava: How to chain calls, depending on result ?

Created on 8 Dec 2014  路  6Comments  路  Source: ReactiveX/RxJava

Hello,

In my webapp, I have to chain two async calls :
The first call gives me a list of dog ids.
The second call gives me a Dog (found by its id).

In my code, i'd like to write something like :

final Observable<RxMessage<String>> observable1 = asyncCallForDogIds(..);

final List<Dog> dogs = new ArrayList<>();
observable1.subscribe(
    // onNext
    (RxMessage<String> message) -> {
        final String id = readId(message);

        final Observable<RxMessage<String>> observable2 = someAsyncCallForOneDogId(id, ..);

        final Dog dog = readFromSomeMessage2(...);
        dogs.add(dog);
    },

    // onError
    (Throwable err) -> error(err, ..),

    // onCompleted
    () -> resume(dogs, ..));

What would be the best way to do that ?
Th.

Question

Most helpful comment

If you want to handle errors for each call you put the onErrorResumeNext or similar handlers on each of the async calls.

asyncCallForDogIds(..)
    .map(this::readId)
    .flatMap(dogId -> {
             return someAsyncCallForOneDogId(id, ..)
                             .onErrorResumeNext(errorHandlingHere)
    })
    .map(this::readFromSomeMessage2)

All 6 comments

You want flatMap so roughly:

asyncCallForDogIds(..)
    .map(this::readId)
    .flatMap(dogId -> someAsyncCallForOneDogId(id, ..))
    .map(this::readFromSomeMessage2)

Yes that looks what I need. Thx. But how do I process the onError and onCompleted ? for each async call

Those will propagate down the chain. If any Observable emits an error it will be sent down to your subscriber.

If you want to handle errors for each call you put the onErrorResumeNext or similar handlers on each of the async calls.

asyncCallForDogIds(..)
    .map(this::readId)
    .flatMap(dogId -> {
             return someAsyncCallForOneDogId(id, ..)
                             .onErrorResumeNext(errorHandlingHere)
    })
    .map(this::readFromSomeMessage2)

Thx for those great answers.

I'm getting a little confused. What about if my first call returns an object that contains many ids, and I have to process the second call for each id :

I was thinking about something like this :

final Observable<RxMessage<String>> observable1 = doCallThatReturnBoxes(userId);

Box box = null;
observable1
    .flatMap(new Func1<RxMessage<String>, Observable<RxMessage<String>>>() 
        public Observable<RxMessage<String>> call(RxMessage<String> message) {
            box = readBoxFromMessage(message);

            final List<String> ids = box.getItemIds();

            // Here I need to call doCallThatReturnOneItemDetails for each id
            // How do I create an Observable from the ids list ?

        }
        .subscribe(
            // onNext
            (RxMessage<String> message) -> {
                final BoxItem boxItem = readBoxItemFromMessage(message);

                box.getItems.add(boxItem);
            },

            // onError
            (Throwable err) -> error(err, response, resp),

            // onCompleted
            () -> resume(response, resp)
        );

And if my first call returns a list of boxies ? like this ?

final List<Box> boxies = new ArrayList<>();
observable1
    .flatMap(new Func1<RxMessage<String>, Observable<RxMessage<String>>>() 
        public Observable<RxMessage<String>> call(RxMessage<String> message) {
            final Box box = readBoxFromMessage(message);
            boxies.add(box);

            final List<String> ids = box.getItemIds();

            // Here I need to call doCallThatReturnOneItemDetails for each id
            // How do I create an Observable from the ids list ?

        }
        .subscribe(
            // onNext
            (RxMessage<String> message) -> {
                final BoxItem boxItem = readBoxItemFromMessage(message);

                // Here how to specify the good box ?
                box.getItems.add(boxItem);
            },

            // onError
            (Throwable err) -> error(err, response, resp),

            // onCompleted
            () -> resume(response, resp)
        );

How do I associate the item details with the good box ?

I'm closing this due to inactivity. If you have further questions, please don't hesitate to reopen this issue or post a new one.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dlew picture dlew  路  4Comments

aballano picture aballano  路  3Comments

perlow picture perlow  路  3Comments

dsvoronin picture dsvoronin  路  4Comments

nltran picture nltran  路  4Comments