Получить данные из двух API, используя RxJava - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть два запроса API

//, чтобы получить список всех продуктов внутри специфика c категории

1. getCategoryProducts : Observable<List<CategoryProductsModel>
       class CategoryProductsModel {
        int categoryId ; 
        String sku ; 

    // sku is variable I used it to get the details for each product (name , images , colors , sizes , price ..etc

        }

//, чтобы получить информация о продукте по sku на основе первого API getCategoryProducts

2.getProductDetails(var sku:String): Observable<ProductDetailsModel> 
       class ProductDetailsModel {
          float price ; 
          List<Images> images , 
          List<Colors> colors , 
          etc ... 
         }

первый запрос getCategoryProducts, затем getProductDetails на основе первого запроса, чтобы получить sku для каждого продукта и передать его getProductDetails

после того, как я сделаю второй запрос, я хочу добавить ответ с данными в ProductModel, чтобы получить, наконец, список ProductModel, чтобы передать его recycler view

 ProductModel 
{
 CategoryProductsModel mCategoryProductsModel ;
 ProductDetailsModel mProductDetailsModel ; 
}

Я использую Rx Java для запроса API. Как я могу это сделать?

public void getProductsList() {

    getCategoryProductsObservable()
            .subscribeOn(Schedulers.io())
            .flatMap(new Function<CategoryProductsModel, ObservableSource<List<ProductModel>>>() {
                @Override
                public ObservableSource<List<ProductModel>> apply(CategoryProductsModel mCategoryProductsModel) throws Exception {
                    return getProductDetails(mCategoryProductsModel);
                }
            }).observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::fillProducts);



}





public Observable<CategoryProductsModel> getCategoryProductsObservable() {
   return Repository.Companion.getStoreInstance().getCategoryProducts(categoryId).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap(new Function<List<CategoryProductsModel>, ObservableSource<CategoryProductsModel>>() {
                @Override
                public ObservableSource<CategoryProductsModel> apply(List<CategoryProductsModel> mCategoryProductsList) throws Exception {
                    return Observable.fromIterable(mCategoryProductsList).subscribeOn(Schedulers.io());
                }
            }).subscribeOn(Schedulers.io());



}




@SuppressLint("CheckResult")
public Observable<List<ProductModel>> getProductDetails(CategoryProductsModel mCategoryProducts) {
    List<ProductModel> mList = new ArrayList<>() ;

    return Repository.Companion.getStoreInstance().getProductDetails(mCategoryProducts.getSku())
            .map(new Function<ProductDetailsModel, List<ProductModel>>() {

                @Override
                public List<ProductModel> apply(ProductDetailsModel mProductDetailsModel) throws Exception {
                    Log.d("mProductDetailsModel", mProductDetailsModel.getName());
                    ProductModel productModel = new ProductModel() ;
                    productModel.setProductDetailsModel(mProductDetailsModel);
                    productModel.setCategoryProductsModel(mCategoryProducts);
                    mList.add(productModel);


                    return mList;
                }
            }).subscribeOn(Schedulers.io());

1 Ответ

0 голосов
/ 14 апреля 2020

список необходимых вам операторов: switchMap() fromIterable() и toList(). Таким образом, ваш код будет выглядеть так:

getCategoryProductsObservable()
        .subscribeOn(Schedulers.io())
        .switchMap { listOfProducts -> Observable.fromIterable(listOfProducts)
                    .map { it.sku }
                    .flatMap { sku -> getProductDetails(sku) }
                    .toList()
                    .map { listOfProductDetails -> /* combine with listOfProducts to Model you need */ }
        }
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(this::fillProducts);

Я использовал лямбды для более короткого ответа, могу переписать в стиле Function, но я думаю, это само за себя.

...