|
|
|
@ -27,26 +27,29 @@ type ApiV3CollectionType<T> = CollectionResource<T>|IHALCollection<T>; |
|
|
|
|
* Extract the elements of either a HAL class or an interface |
|
|
|
|
*/ |
|
|
|
|
function extractCollectionElements<T>(collection:ApiV3CollectionType<T>):T[] { |
|
|
|
|
// Some API endpoints return an undefined _embedded.elements
|
|
|
|
|
// so we ensure we return an array at all times.
|
|
|
|
|
if (collection instanceof HalResource) { |
|
|
|
|
return collection.elements; |
|
|
|
|
return collection.elements || []; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return collection._embedded.elements; |
|
|
|
|
return collection._embedded?.elements || []; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get ALL pages of a potentially paginated APIv3 request. |
|
|
|
|
* Get ALL pages of a potentially paginated APIv3 request, returning an array of collections |
|
|
|
|
* |
|
|
|
|
* @param request The requesting callback to request specific pages |
|
|
|
|
* @param pageSize The pageSize parameter to request, defaults to -1 (the maximum magic page number) |
|
|
|
|
* @return an array of HAL collections |
|
|
|
|
*/ |
|
|
|
|
export function getPaginatedResults<T>( |
|
|
|
|
request:(params:ApiV3PaginationParameters) => Observable<ApiV3CollectionType<T>>, |
|
|
|
|
export function getPaginatedCollections<T, C extends ApiV3CollectionType<T>>( |
|
|
|
|
request:(params:ApiV3PaginationParameters) => Observable<C>, |
|
|
|
|
pageSize = MAGIC_PAGE_NUMBER, |
|
|
|
|
):Observable<T[]> { |
|
|
|
|
):Observable<ApiV3CollectionType<T>[]> { |
|
|
|
|
return request({ pageSize, offset: 1 }) |
|
|
|
|
.pipe( |
|
|
|
|
mergeMap((collection:ApiV3CollectionType<T>) => { |
|
|
|
|
mergeMap((collection:C) => { |
|
|
|
|
const resolvedSize = collection.pageSize; |
|
|
|
|
|
|
|
|
|
if (collection.total > collection.count) { |
|
|
|
@ -58,20 +61,36 @@ export function getPaginatedResults<T>( |
|
|
|
|
|
|
|
|
|
// Branch out and fetch all remaining pages in parallel.
|
|
|
|
|
// Afterwards, merge the resulting list
|
|
|
|
|
return forkJoin(...calls).pipe( |
|
|
|
|
map( |
|
|
|
|
(results:ApiV3CollectionType<T>[]) => results.reduce( |
|
|
|
|
(acc, next) => acc.concat(extractCollectionElements(next)), |
|
|
|
|
extractCollectionElements(collection), |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
); |
|
|
|
|
return forkJoin(...calls) |
|
|
|
|
.pipe( |
|
|
|
|
map((results:C[]) => [collection, ...results]), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The current page is the only page, return the results.
|
|
|
|
|
return of(extractCollectionElements(collection)); |
|
|
|
|
return of([collection]); |
|
|
|
|
}), |
|
|
|
|
// Elements may incorrectly be undefined here due to the way the representer works
|
|
|
|
|
map((elements) => elements || []), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Get ALL pages of a potentially paginated APIv3 request, returning all concatenated elements. |
|
|
|
|
* |
|
|
|
|
* @param request The requesting callback to request specific pages |
|
|
|
|
* @param pageSize The pageSize parameter to request, defaults to -1 (the maximum magic page number) |
|
|
|
|
* @return an array of plain HAL resources |
|
|
|
|
*/ |
|
|
|
|
export function getPaginatedResults<T>( |
|
|
|
|
request:(params:ApiV3PaginationParameters) => Observable<ApiV3CollectionType<T>>, |
|
|
|
|
pageSize = MAGIC_PAGE_NUMBER, |
|
|
|
|
):Observable<T[]> { |
|
|
|
|
return getPaginatedCollections(request, pageSize) |
|
|
|
|
.pipe( |
|
|
|
|
map( |
|
|
|
|
(results:ApiV3CollectionType<T>[]) => results.reduce( |
|
|
|
|
(acc, next) => acc.concat(extractCollectionElements(next)), |
|
|
|
|
[] as T[], |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|