2016-07-03 3 views
0

Скажем, например, у меня был класс:Multiple API вызовов создать объект

public class NI { 

    private int id; 
    @SerializedName("date") 
    private String created_at; 
    private String slug; 
    private String type; 
    private String link; 

    private WPTitle title; 

    private WPContent content; 

    private WPExcerpt excerpt; 
    @SerializedName("author") 
    private int authorId; 
    private int featured_media; 
    private WPMedia media; 
    List<Integer> categories; 
} 

И еще один класс:

public class WPMedia { 
    private int id; 
    private String media_type; 
    private String mime_type; 
    private String source_url; 
} 

Вопрос заключается в том, что WPMedia требует отдельного вызова API на основе на значение int featured_media. Как бы я построил наблюдаемую цепочку, чтобы получить класс NI, а затем другой, чтобы получить WPMedia, а затем установить его на объект?

Я использую Дооснащение сделать API вызовы, как это:

@GET("wp-json/wp/v2/posts") 
Observable<ArrayList<NI>>getPostsObservableByCategory(@Query("categories") int category, @Query ("per_page") int limit, @Query("page") int skip); 

@GET("wp-json/wp/v2/media/{id}") 
Observable<WPMedia> getMediaObservable(@Path("id") int id); 

ответ

1

Это еще не совсем ясно мне, что вы хотите точно, но я дам ему выстрелили.

Предположение, что я делаю сначала, это то, что на NI у вас есть сеттер с подписью public void setWPMedia(WPMedia media). Учитывая два Retrofit определения функции вы даете, я бы сказал, что вы делаете следующее:

getPostsObservableByCategory(...) 
    .flatMap(nis -> getMediaObservable(...) 
    .first() 
    .doOnNext(m -> nis.foreach(ni -> ni.setWPMedia(m))) 
    .map(m -> nis)); 

Переход на эту линию по линии:

  • getPostsObservableByCategory(...) дает вам Observable, испускающий списки NI экземпляров. Поле media на каждом NI в этих списках может быть уже установлено или не установлено.
  • getMediaObservable(...) получает экземпляр WPMedia, который должен быть установлен на каждый элемент в соответствующем списке.
  • Я ограничиваю количество выбросов getMediaObservable, иначе поле в NI будет установлено несколько раз, что, я полагаю, не очень желательно. Вы можете пропустить эту строку, если это уже гарантировано функцией/реализацией getMediaObservable(...).
  • Установка поля считается побочным эффектом, поэтому нам нужен doOnNext здесь, в котором мы прокручиваем список экземпляров NI и задаем поле WPMedia тому, что получено от getMediaObservable.
  • Я предполагаю, что вы хотите иметь список NI экземпляров, поэтому я добавил map, который просто заменяет m на этот список.

Надеюсь, это поможет вам!

+0

Класс NI должен быть загружен первым, так что feature_media INT может быть доступен, а затем он передается getMediaObservable вызова. Если я правильно понимаю ваш пример, я не вижу, как указанный int передается вызову getMediaObservable. Мне ясно? –

+0

А в этом случае это должно быть примерно следующее: 'getPostsObservableByCategory (...). FlatMap (nis -> Observable.from (nis) .flatMap (ni -> getMediaObservable (ni.getFeatureMedia) .first() .doOnNext (ni :: setWPMedia) .map (m -> ni))) '.Вы помещаете список 'nis' в' Observable' и 'flatMap' над каждым элементом, вызывая' getMediaObservable' с полем 'featureMedia' (через getter) из каждого' ni'. – RvanHeest

+0

Я получаю «переменная-вывод R имеет несовместимые границы» компилировать ошибку из .map (m -> ni) –

0

Я нахожу для вас демо! Я думаю, что вы можете сделать, как показано ниже:

@GET("/token") 
public Observable<String> getToken(); 

@GET("/user") 
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId); 

... 

getToken() 
.flatMap(new Func1<String, Observable<User>>() { 
    @Override 
    public Observable<User> onNext(String token) { 
     return getUser(token, userId); 
    }) 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(new Observer<User>() { 
    @Override 
    public void onNext(User user) { 
     userView.setUser(user); 
    } 

    @Override 
    public void onCompleted() { 
    } 

    @Override 
    public void onError(Throwable error) { 
     // Error handling 
     ... 
    } 
}); 

Blog Link

Смежные вопросы