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:

  1. upload list of logos
    • receive result of logos upload more detailed data of logos uploaded.
  2. use list of results got , use in new request make create book.
    • receive newly create book response book more auto generated data
  3. get current author/user info ( forced make observable because single doesn't work .zip operator )
  4. 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

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -