3

I cant find a way to combine or chain a list of observables that it´s responses are prerequisites to other call that creates another Observable.

I´m using retrofit with observables.

My Service:

String url = "/geocode/json?sensor=false";

@GET(url)
Observable<GeocodeResult> getReverse(@Query("key") String gMapsKey,
                                     @Query("latlng") LatLng origin);

And another service needs that GeocodeResult

@POST("/api/orders")
Observable<Order> createOrder(@Body GeocodeResult newOrder);
  1. And I´m trying with:

    // Prerequisite 1 Observable geocodeObservable = Address.get(...);

    // Call createOrder after geocode is obtained? return Observable.combineLatest(geocodeObservable, geocode -> createOrder(geocode));

But it don´t work because combineLatest needs an object, not an observable but I need to return the observable.

With JoinObservable:

Pattern5<Geocode> pattern = JoinObservable.from(geocodeObservable)
Plan0<Observable<Order>> plan = pattern.then(Order::create);
return JoinObservable.when(plan).toObservable().toBlocking().single();

But it throws an NoSuchElementException exception. Why?

I do toBlocking().single() because I need the Observable and not the Observable<Observable<Order>> :(.

Or how can I do it?

2 Answers 2

6

You could try using flatMap which can take the second observable as an parameter.

The function takes the items emitted by the first observable and creates an observable for each of those items and then flattens the items emitted by those observables into a single observable. This sounds complex, but fortunately both your Retrofit functions emit only a single item, so only one observable gets "flattened" into a observable.

You can use flatMap like this:

restApi.getReverse(gMapsKey, origin)
    .flatMap(geocodeResult -> createOrder(geocodeResult))
    .subscribe(order -> doSomething(order));

combineLatest doesn't really fit your needs, because it would perform both REST calls at the same time, not one after the other, so you can't use the response of the first one as the parameter of the second. I can't comment on why the exception gets thrown for JoinObservable because it's not a part of any public API. Also toBlocking() shouldn't really be used for anything other than testing.

Sign up to request clarification or add additional context in comments.

2 Comments

But what happens if I have more than 1 requisite? I mean more than 1 observable to wait until createOrder ? I remean, if create order takes 2 parameters created from 2 observables?
@Caipivara Try doing combineLatest on the two observable which will give you one observable and on that apply flatMap
2

I ended up creating a new Object and using Observable.combineLatest to combine all the prerequisites creating a new Observable and then using flatMap to create the new Observable from that observable.

Observable<NewOrderWrapper> newOrderObservable = Observable.combineLatest(prerequisites, (param1, param2,...) -> {return new NewOrderWrapper(param1, param2,...)});

and then

Observable<Order> finalOrderObservable = newOrderObservable.flatMap(newOrderWrapper -> create(newOrderWrapper))

Check a post here MakinGIANST/RXJava post.

Thanks to @LukaCiko

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.