Commits

Giuseppe Digilio authored ac36cc20dcf
[CST-6876] Refactoring in order to remove nested subscriptions
No tags

src/app/shared/search/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts

Modified
1 +import { animate, state, style, transition, trigger } from '@angular/animations';
2 +import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
3 +import { Router } from '@angular/router';
4 +
1 5 import {
2 6 BehaviorSubject,
3 7 combineLatest as observableCombineLatest,
4 8 Observable,
5 9 of as observableOf,
6 10 Subject,
7 11 Subscription
8 12 } from 'rxjs';
9 -import { distinctUntilChanged, filter, map, switchMap, take, tap } from 'rxjs/operators';
10 -import { animate, state, style, transition, trigger } from '@angular/animations';
11 -import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
12 -import { Router } from '@angular/router';
13 +import { distinctUntilChanged, filter, map, mergeMap, switchMap, take, tap } from 'rxjs/operators';
14 +
13 15 import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
14 16 import { PaginatedList } from '../../../../../core/data/paginated-list.model';
15 17 import { RemoteData } from '../../../../../core/data/remote-data';
16 18 import { hasNoValue, hasValue, isNotEmpty } from '../../../../empty.util';
17 19 import { EmphasizePipe } from '../../../../utils/emphasize.pipe';
18 20 import { FacetValue } from '../../../models/facet-value.model';
19 21 import { SearchFilterConfig } from '../../../models/search-filter-config.model';
20 22 import { SearchService } from '../../../../../core/shared/search/search.service';
21 23 import {
22 24 FILTER_CONFIG,
25 27 SearchFilterService
26 28 } from '../../../../../core/shared/search/search-filter.service';
27 29 import { SearchConfigurationService } from '../../../../../core/shared/search/search-configuration.service';
28 30 import { getFirstSucceededRemoteData } from '../../../../../core/shared/operators';
29 31 import { InputSuggestion } from '../../../../input-suggestions/input-suggestions.model';
30 32 import { SearchOptions } from '../../../models/search-options.model';
31 33 import { SEARCH_CONFIG_SERVICE } from '../../../../../my-dspace-page/my-dspace-page.component';
32 34 import { currentPath } from '../../../../utils/route.utils';
33 35 import { getFacetValueForType, stripOperatorFromFilterValue } from '../../../search.utils';
34 36 import { createPendingRemoteDataObject } from '../../../../remote-data.utils';
37 +import { FacetValues } from '../../../models/facet-values.model';
35 38
36 39 @Component({
37 40 selector: 'ds-search-facet-filter',
38 41 template: ``,
39 42 })
40 43
41 44 /**
42 45 * Super class for all different representations of facets
43 46 */
44 47 export class SearchFacetFilterComponent implements OnInit, OnDestroy {
69 72
70 73 /**
71 74 * Emits the result values for this filter found by the current filter query
72 75 */
73 76 filterSearchResults: Observable<InputSuggestion[]> = observableOf([]);
74 77
75 78 /**
76 79 * Emits the active values for this filter
77 80 */
78 81 selectedValues$: Observable<FacetValue[]>;
82 +
79 83 protected collapseNextUpdate = true;
80 84
81 85 /**
82 86 * State of the requested facets used to time the animation
83 87 */
84 88 animationState = 'loading';
85 89
86 90 /**
87 91 * Emits all current search options available in the search URL
88 92 */
277 281
278 282 protected retrieveFilterValues(useCachedVersionIfAvailable = true) {
279 283 const facetValues$ = observableCombineLatest([this.searchOptions$, this.currentPage]).pipe(
280 284 map(([options, page]) => {
281 285 return { options, page };
282 286 }),
283 287 switchMap(({ options, page }) => {
284 288 return this.searchService.getFacetValuesFor(this.filterConfig, page, options, null, useCachedVersionIfAvailable)
285 289 .pipe(
286 290 getFirstSucceededRemoteData(),
287 - map((results) => {
288 - return {
289 - values: observableOf(results),
290 - page: page
291 - };
292 - }
291 + tap((rd: RemoteData<FacetValues>) => {
292 + this.isLastPage$.next(hasNoValue(rd?.payload?.next));
293 + }),
294 + map((rd: RemoteData<FacetValues>) => ({
295 + values: observableOf(rd),
296 + page: page
297 + })
293 298 )
294 299 );
295 300 })
296 301 );
297 302
298 303 let filterValues = [];
299 - this.subs.push(facetValues$.subscribe((facetOutcome) => {
300 - const newValues$ = facetOutcome.values;
301 -
302 - if (this.collapseNextUpdate) {
303 - this.showFirstPageOnly();
304 - facetOutcome.page = 1;
305 - this.collapseNextUpdate = false;
306 - }
307 - if (facetOutcome.page === 1) {
308 - filterValues = [];
309 - }
310 -
311 - filterValues = [...filterValues, newValues$];
312 -
313 - this.subs.push(this.rdbs.aggregate(filterValues).pipe(
304 + this.subs.push(
305 + facetValues$.pipe(
306 + mergeMap((facetOutcome) => {
307 + const newValues$ = facetOutcome.values;
308 +
309 + if (this.collapseNextUpdate) {
310 + this.showFirstPageOnly();
311 + facetOutcome.page = 1;
312 + this.collapseNextUpdate = false;
313 + }
314 + if (facetOutcome.page === 1) {
315 + filterValues = [];
316 + }
317 +
318 + filterValues = [...filterValues, newValues$];
319 +
320 + return this.rdbs.aggregate(filterValues);
321 + }),
314 322 tap((rd: RemoteData<PaginatedList<FacetValue>[]>) => {
315 323 this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig).pipe(
316 324 map((selectedValues) => {
317 325 return selectedValues.map((value: string) => {
318 - const fValue = [].concat(...rd.payload.map((page) => page.page)).find((facetValue: FacetValue) => this.getFacetValue(facetValue) === value);
326 + const fValue = [].concat(...rd.payload.map((page) => page.page))
327 + .find((facetValue: FacetValue) => this.getFacetValue(facetValue) === value);
319 328 if (hasValue(fValue)) {
320 329 return fValue;
321 330 }
322 331 const filterValue = stripOperatorFromFilterValue(value);
323 332 return Object.assign(new FacetValue(), { label: filterValue, value: filterValue });
324 333 });
325 334 })
326 335 );
327 336 })
328 337 ).subscribe((rd: RemoteData<PaginatedList<FacetValue>[]>) => {
329 338 this.animationState = 'ready';
330 339 this.filterValues$.next(rd);
331 -
332 - }));
333 - this.subs.push(newValues$.pipe(take(1)).subscribe((rd) => {
334 - this.isLastPage$.next(hasNoValue(rd.payload.next));
335 - }));
336 - }));
340 + })
341 + );
337 342 }
338 343
339 344 /**
340 345 * Transforms the facet value string, so if the query matches part of the value, it's emphasized in the value
341 346 * @param {FacetValue} facet The value of the facet as returned by the server
342 347 * @param {string} query The query that was used to search facet values
343 348 * @returns {string} The facet value with the query part emphasized
344 349 */
345 350 getDisplayValue(facet: FacetValue, query: string): string {
346 351 return new EmphasizePipe().transform(facet.value, query) + ' (' + facet.count + ')';

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut