2016-05-04 1 views
3

Я знаю, как обращаться с ответами Retrofit, но у меня проблема с обработкой разбиения на страницы из REST API с помощью rx java.Как справиться с разбиением на страницы с помощью Retrofit 2 и RxJava

фон

АНЯ остального, что я использую дает мне следующий ответ со ссылкой на следующую страницу в заголовках:

HTTP 200 OK 
Allow: GET, HEAD, OPTIONS 
Content-Type: application/json 
Link: <http://some-endpoint.com/pictures?page=2>; rel="next" 
Vary: Accept 
X-Total-Count: 80 

[ 
    { 
     "id": 3, 
     "url": "", 
     "picture": { 
      "id": 6, 
      "url": "", 
      "name": "Chrysler" 
     }, 
     "location": { 
      "type": "Point", 
      "coordinates": [ 
       10.108956, 
       41.389576000000005 
      ] 
     } 
    }, 
    { 
     "id": 4, 
     "url": "", 
     "picture": { 
      "id": 26, 
      "url": "", 
      "name": "Douglas Aircraft" 
     }, 
     "location": { 
      "type": "Point", 
      "coordinates": [ 
       10.1977759999999997, 
       41.426645 
      ] 
     } 
    }, 
... 
} 

Права знает, что я сумел получить пагинацию запрос на страницу 2 со следующим кодом, но я не знаю, как сделать эти запросы на разбиение на страницы до тех пор, пока в ответе не будет «следующей» ссылки заголовка, чтобы я мог сохранять все данные из всех запросов в базу данных.

private Observable<List<PictureEntity>> getPictures(final LocationEntity locationEntity) { 
    if (getDataFromServer()) { 
     return mApiService.getPictures() 
       .concatMap(new Func1<Response<List<Picture>>, Observable<Response<List<Picture>>>>() { 
        @Override 
        public Observable<Response<List<Picture>>> call(Response<List<Picture>> listResponse) { 
         String link = NetworkUtil.getNextLinkPaginate(listResponse.headers().get("Link")); 
         Timber.i(link); 
         return Observable.just(listResponse) 
           .concatWith(mApiService.getPicturesPaginate(link)) 
           .reduce(new Func2<Response<List<Picture>>, Response<List<Picture>>, 
             Response<List<Picture>>>() { 
            @Override 
            public Response<List<Picture>> call(Response<List<Picture>> listResponse, 
                      Response<List<Picture>> listResponse2) { 
             listResponse.body().addAll(listResponse2.body()); 
             return listResponse; 
            } 
           }); 
        } 
       }) 
       .concatMap(new Func1<Response<List<Picture>>, Observable<List<PictureEntity>>>() { 
        @Override 
        public Observable<List<PictureEntity>> call(Response<List<Picture>> listResponse) { 
         List<PictureEntity> pictureEntities = 
           mPictureDataMapper.transformToEntity(listResponse.body()); 
         mDatabaseHelper.setPictureEntity(pictureEntities).subscribe(); 
         return mDatabaseHelper.getNearbyPicturesEntity(locationEntity); 
        } 
       }); 
    } else { 
     return mDatabaseHelper.getNearbyPicturesEntity(locationEntity); 
    } 
} 

Любые предложения по обращению с такими запросами? Может быть .takeUntil оператор?

ответ

-2

Вы можете использовать concatMap с некоторой рекурсией.

Observable<List<PointOfSaleEntity>> getPointsOfSalePaginateUntilEnd(String link) { 
    if (link.equals("")) { 
     return Observable.empty(); 
    } else {  
     return mApiService.getPointsOfSalesPaginate(link)      
         .concatMap(listResponse -> Observable.concat(Observable.just(listResponse),mApiService.getPointsOfSalesPaginate(NetworkUtil.getNextLinkPaginate(listResponse.headers().get("Link"))))); 
    } 
} 

Observable<List<PointOfSaleEntity>> getPointsOfSalePaginateUntilEnd() { 
     return mApiService.mApiService.getPointsOfSales()       
         .concatMap(listResponse -> Observable.concat(Observable.just(listResponse),mApiService.getPointsOfSalesPaginate(NetworkUtil.getNextLinkPaginate(listResponse.headers().get("Link"))))); 
} 
+0

Это самый сложный код для чтения, который я когда-либо видел! –