java - Simplifying Retrofit2 and Rxjava2 chained calls to use a Single instead of Observable in the final result -
what want accomplish update calls @ end of all, when subscribe, return single , not observable because ever receive 1 result due nature of combining calls, had move observable take advantage of observable methods join results single result.
the issue having trying figure out how use results 1 call , combine result 1 , return combination of both.
the sequence of calls follows:
- upload list of logos
- receive result of logos upload more detailed data of logos uploaded.
- use list of results got , use in new request make create book.
- receive newly create book response book more auto generated data
- get current author/user info ( forced make observable because single doesn't work .zip operator )
- use author result , book details create pojo object. return final result. currently, returned observable there ever 1 entry returned makes little sense return observable. not sure how can transform return single appreciate suggestions.
this code have right now. objects , such example sequence , calls have:
retrofit service:
@get("/api/profile/author") observable<authorjson> getauthor(); @post("/api/logo") observable<booklogojson> uploadbooklogos(@header("content-type") string content_type, @body requestbody logo); @post("/api/book") single<bookdetailsjson> newbook(@body bookdetailrequest request);
the actual implementation
list<book> booklogos = ...; observable.fromiterable(booklogos) .subscribeon(schedulers.io()) .observeon(schedulers.io()) .flatmap(new function<string, observablesource<booklogojson>>() { @override public observablesource<booklogojson> apply(@nonnull string booklogos) throws exception { return mapi.uploadbooklogos(mcontenttype, getrequestbody(booklogos, context)); } }).tolist().flatmap(new function<list<booklogojson>, singlesource<bookdetailsjson>>() { @override public singlesource<bookdetailsjson> apply(@nonnull list<booklogojson> booklogosraw) throws exception { bookdetailrequest request = new bookdetailrequest(); for(booklogojson logo : booklogosraw){ request.mlogos.add(logo.mid); } return mapi.newbook(request); } }).toobservable().flatmap(new function<bookdetailsjson, observablesource<book>>() { @override public observablesource<book> apply(@nonnull bookdetailsjson bookdetailsjson) throws exception { return observable.zip(mapi.getauthor(), observable.just(bookdetailsjson), new bifunction<authorjson, bookdetailsjson, book>() { @override public book apply(authorjson author, bookdetailsjson bookdetails) throws exception { return mconverter.getbook(author, bookdetails); } }); } }) .observeon(androidschedulers.mainthread()) .subscribewith(new observer<book>() { @override public void onsubscribe(@nonnull disposable d) { } @override public void onnext(@nonnull book book) { // here, ever 1 book observable makes no sense. } @override public void onerror(@nonnull throwable e) { } @override public void oncomplete() { } });
it quite simple, since result tolist().flatmap(...)
single
.
simply remove call toobservable()
, modify flatmap
afterwards return single
:
mapi.getauthor().firstorerror().map(new function<authorjson, book>() { public book apply(@nonnull authorjson author) throws exception { // bookdetails captured anonymous function return mconverter.getbook(author, bookdetails); } });
in addition, retrofit's rxjava converter accepts single
replacement observable
. might apply here since requests produce single result or error. (completable
can used no-response requests)
Comments
Post a Comment