import { Observable } from 'rxjs/Observable'; import { filter, first, flatMap, map, tap } from 'rxjs/operators'; import { hasValueOperator, isNotEmpty } from '../../shared/empty.util'; import { DSOSuccessResponse } from '../cache/response-cache.models'; import { ResponseCacheEntry } from '../cache/response-cache.reducer'; import { ResponseCacheService } from '../cache/response-cache.service'; import { RemoteData } from '../data/remote-data'; import { RestRequest } from '../data/request.models'; import { RequestEntry } from '../data/request.reducer'; import { RequestService } from '../data/request.service'; import { BrowseDefinition } from './browse-definition.model'; import { DSpaceObject } from './dspace-object.model'; import { PaginatedList } from '../data/paginated-list'; import { SearchResult } from '../../+search-page/search-result.model'; /** * This file contains custom RxJS operators that can be used in multiple places */ export const getRequestFromSelflink = (requestService: RequestService) => (source: Observable): Observable => source.pipe( flatMap((href: string) => requestService.getByHref(href)), hasValueOperator() ); export const getResponseFromSelflink = (responseCache: ResponseCacheService) => (source: Observable): Observable => source.pipe( flatMap((href: string) => responseCache.get(href)), hasValueOperator() ); export const filterSuccessfulResponses = () => (source: Observable): Observable => source.pipe(filter((entry: ResponseCacheEntry) => entry.response.isSuccessful === true)); export const getResourceLinksFromResponse = () => (source: Observable): Observable => source.pipe( filterSuccessfulResponses(), map((entry: ResponseCacheEntry) => (entry.response as DSOSuccessResponse).resourceSelfLinks), ); export const configureRequest = (requestService: RequestService) => (source: Observable): Observable => source.pipe(tap((request: RestRequest) => requestService.configure(request))); export const getRemoteDataPayload = () => (source: Observable>): Observable => source.pipe(map((remoteData: RemoteData) => remoteData.payload)); export const getSucceededRemoteData = () => (source: Observable>): Observable> => source.pipe(first((rd: RemoteData) => rd.hasSucceeded)); export const toDSpaceObjectListRD = () => (source: Observable>>>): Observable>> => source.pipe( map((rd: RemoteData>>) => { const dsoPage: T[] = rd.payload.page.map((searchResult: SearchResult) => searchResult.dspaceObject); const payload = Object.assign(rd.payload, { page: dsoPage }) as any; return Object.assign(rd, {payload: payload}); }) ); /** * Get the browse links from a definition by ID given an array of all definitions * @param {string} definitionID * @returns {(source: Observable>) => Observable} */ export const getBrowseDefinitionLinks = (definitionID: string) => (source: Observable>): Observable => source.pipe( getRemoteDataPayload(), map((browseDefinitions: BrowseDefinition[]) => browseDefinitions .find((def: BrowseDefinition) => def.id === definitionID && def.metadataBrowse === true) ), map((def: BrowseDefinition) => { if (isNotEmpty(def)) { return def._links; } else { throw new Error(`No metadata browse definition could be found for id '${definitionID}'`); } }) );