Reputation: 15936
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);
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?
Upvotes: 3
Views: 1931
Reputation: 15936
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
Upvotes: 2
Reputation: 4445
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.
Upvotes: 6