Skip to content
Snippets Groups Projects
comcol-data.service.ts 2.73 KiB
Newer Older
import { distinctUntilChanged, filter, map, mergeMap, share, take, tap } from 'rxjs/operators';
lotte's avatar
lotte committed
import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs';
import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CommunityDataService } from './community-data.service';

import { DataService } from './data.service';
import { FindAllOptions, FindByIDRequest } from './request.models';
import { HALEndpointService } from '../shared/hal-endpoint.service';
lotte's avatar
lotte committed
import { getResponseFromEntry } from '../shared/operators';
lotte's avatar
lotte committed
import { CacheableObject } from '../cache/object-cache.reducer';
export abstract class ComColDataService<T extends CacheableObject> extends DataService<T> {
  protected abstract cds: CommunityDataService;
  protected abstract objectCache: ObjectCacheService;
  protected abstract halService: HALEndpointService;

  /**
   * Get the scoped endpoint URL by fetching the object with
   * the given scopeID and returning its HAL link with this
Art Lowel's avatar
Art Lowel committed
   * data-service's linkPath
   *
   * @param {string} scopeID
   *    the id of the scope object
   * @return { Observable<string> }
   *    an Observable<string> containing the scoped URL
   */
lotte's avatar
lotte committed
  public getBrowseEndpoint(options: FindAllOptions = {}, linkPath: string = this.linkPath): Observable<string> {
lotte's avatar
lotte committed
      return this.halService.getEndpoint(linkPath);
    } else {
lotte's avatar
lotte committed
      const scopeCommunityHrefObs = this.cds.getEndpoint().pipe(
lotte's avatar
lotte committed
        map((endpoint: string) => this.cds.getIDHref(endpoint, options.scopeID)),
lotte's avatar
lotte committed
        filter((href: string) => isNotEmpty(href)),
        take(1),
        tap((href: string) => {
          const request = new FindByIDRequest(this.requestService.generateRequestId(), href, options.scopeID);
          this.requestService.configure(request);
lotte's avatar
lotte committed
        }));
lotte's avatar
lotte committed
      const responses = scopeCommunityHrefObs.pipe(
lotte's avatar
lotte committed
        mergeMap((href: string) => this.requestService.getByHref(href)),
        getResponseFromEntry()
      );
lotte's avatar
lotte committed
      const errorResponses = responses.pipe(
        filter((response) => !response.isSuccessful),
        mergeMap(() => observableThrowError(new Error(`The Community with scope ${options.scopeID} couldn't be retrieved`)))
lotte's avatar
lotte committed
      );
lotte's avatar
lotte committed
      const successResponses = responses.pipe(
        filter((response) => response.isSuccessful),
lotte's avatar
lotte committed
        mergeMap(() => this.objectCache.getObjectByUUID(options.scopeID)),
lotte's avatar
lotte committed
        map((nc: NormalizedCommunity) => nc._links[linkPath]),
lotte's avatar
lotte committed
        filter((href) => isNotEmpty(href))
      );

lotte's avatar
lotte committed
      return observableMerge(errorResponses, successResponses).pipe(distinctUntilChanged(), share());