2016-02-10 11 views
5

Sto tentando di utilizzare il retrofit + rxjava per effettuare chiamate api nidificate. Fondamentalmente devo costruire un elenco di oggetti Library. Ogni oggetto Libreria ha un elenco di Autori e ogni oggetto Autore ha un elenco di Libri. Ecco come è strutturato il mio json.Concatenare le chiamate di retrofit con RxJava e restituire l'oggetto principale

JSON Biblioteca -

{ 
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" 
     } 
    ] 
} 

E Autori 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" 
     } 
    ] 
} 

E Libri 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." 
    } 
} 
] 
} 

mia interfaccia API è riportata qui sotto.

@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(...); 

Sto provando a costruire un oggetto Librarylist che posso utilizzare per aggiornare l'interfaccia utente. Sono un po 'bloccato qui. Dopo aver effettuato le chiamate multiple, come posso salvare i risultati e raccogliere tutto in un elenco di oggetti libreria?

+0

Potrebbe essere che dovresti provare '.toList()'? – Alexander

+0

Perché hai bisogno di chiedere agli autori e ai loro libri se sei interessato solo alle biblioteche? Se hai bisogno di qualcosa come SQL iscriviti qui, devi costruire un'altra classe, LibraryWithAuthorsWithBooks –

+0

@KirillGamazkov, La mia biblioteca POJO contiene l'elenco e Autore POJO contiene Libro dei libri. Quindi devo compilare tutto e ottenere l'oggetto Libreria – Sammys

risposta

3
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 chiamate .subscribe(). Sono utilizzati per avviare l'esecuzione dell'intera catena. RxObservable non fa nulla fino all'arrivo del sottoscrittore.

+0

Come si riprova il secondo abbonamento se lo stato è fallito? per esempio ho bisogno di controllare lo stato della mia richiesta dal server e se ho ottenuto "lo stato di attesa", allora ho bisogno di inviare nuovamente una richiesta fino a ottenere uno "stato di procedere" e quindi procedere con l'ultimo processo di sottoscrizione. – neilQ5

+0

Non sono abbastanza sicuro di seguirti. RxJava offre molti metodi per affrontare il nuovo tentativo, a partire da # ripetizione osservabile e un paio di altri. Se nessuno di essi sembra adattarsi alle tue esigenze, puoi incapsulare la logica di riprogrammazione nel tuo 'myRestInterface.getLibraryList()', oppure estrarlo in un pezzo di codice riutilizzabile e usarlo insieme a Complessibile # comporre –

+0

tl; dr - in pratica, puoi solo metti .retry() appena prima .subscribe(), fa questo il trucco per te? –

Problemi correlati