Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining Retrofit calls with RxJava and returning the main object

I am trying to use retrofit +rxjava to make nested api calls. Basically I have to construct a List of Library objects. Each Library object has a list of Authors and each Author object has a list of Books. This is how my json is structured.

Library json -

{
 title: "Library",
 items: [
      {
        title: "Library1"
        image: "http://example.com/image/101/image_lib1.png"
        url: "http://example.com/api/1"
      },
      {
        title:"Library2"
        image: "http://example.com/image/101/image_lib2.png"
        url: "http://example.com/api/2"
      },
      {
        title:"Library3"
        image: "http://example.com/image/101/image_lib3.png"
        url: "http://example.com/api/3"
      }
   ]
 }

And Authors json-

{
 title: "Authors",
 items: [
      {
        title: "J.K Rowling"
        image: "http://example.com/image/101/image_author1.png"
        url: "http://example.com/api/101"
      },
      {
        title:"Mark Twain"
        image: "http://example.com/image/101/image_author2.png"
        url: "http://example.com/api/201"
      },
      {
        title:"Charles Dickens"
        image: "http://example.com/image/101/image_author3.png"
        url: "http://example.com/api/301"
      }
   ]
 }

And Books json-

{
description: Books,
imageurl: "http://example.com/image/101/image_101.png",
items: [
   {
     id: 101,
     title: "Oliver Twist ",
     description: "some description"
   },
  {
   id: 1011,
   title: "Hard times",
   description: "some more description."
  }
}
]
}

My api interface is given below.

  @GET("/api/")
  Observable<LibraryResponse> getLibraryList();

  @GET("/api/{feedId}")
  Observable<AuthorResponse> getAuthorList(@Path("feedId") String feedId);

  @GET("/api/{feedId}")
  Observable<BooksResponsee> getBooksList(@Path("feedId") String feedId);




Observable<List<Library>> observable = myRestInterface
    .getLibraryList()
    .map(a -> a.getItems())
    .flatMapIterable(b -> b)                 
    .flatMap(h -> myRestInterface                                                                 
                  .getAuthorList(h.getUrl().substring(h.getUrl().lastIndexOf("/") + 1))                                       
                  .map(x -> x.getItems())
                  .flatMapIterable(l -> l)
                  .flatMap(e -> myRestInterface
                                .getBooksList(e.getUrl().substring(e.getUrl().lastIndexOf("/") + 1))
                                .map(d -> d.getItems())
                                .flatMapIterable(c -> c)))

    .collect(// ? into list of main object)
    .doOnNext(mainObjectList -> new ViewupdateMethod(mainObjectList));
    .subscribe(...);

I am trying to construct one Librarylist object that I can use to update my UI. I am kind of stuck here. After making the multiple calls, how do I save the results back and collect everything to a list of library object?

like image 934
Sammys Avatar asked Oct 18 '22 15:10

Sammys


1 Answers

    Observable<List<Library>> observable = myRestInterface
            .getLibraryList()
            .flatMapIterable(response -> response.getItems())
            .doOnNext(library -> myRestInterface
                    .getAuthorList(library.getUrl().substring(library.getUrl().lastIndexOf("/") + 1))
                    .flatMapIterable(response -> response.getItems())
                    .doOnNext(author -> library.getAuthors().add(author))
                    .doOnNext(
                            author -> myRestInterface
                                    .getBooksList(author.getUrl().substring(author.getUrl().lastIndexOf("/") + 1))
                                    .flatMapIterable(response -> response.getItems())
                                    .doOnNext(book -> author.getBooks().add(book))
                                    .subscribe()
                    )
                    .subscribe()
            )

            .doOnNext(mainObjectList -> new ViewupdateMethod(mainObjectList))
            .subscribe();

Note .subscribe() calls. They are used to start execution of the whole chain. RxObservable does nothing until subscriber arrives.

like image 127
Kirill Gamazkov Avatar answered Oct 21 '22 05:10

Kirill Gamazkov