diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts index bdad302737..49141c2b68 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts @@ -66,7 +66,7 @@ describe('SearchFacetFilterComponent', () => { { provide: Router, useValue: new RouterStub() }, { provide: FILTER_CONFIG, useValue: new SearchFilterConfig() }, { provide: RemoteDataBuildService, useValue: {aggregate: () => Observable.of({})} }, - { provide: SearchConfigurationService, useValue: {getSearchOptions: () => Observable.of({})} }, + { provide: SearchConfigurationService, useValue: {searchOptions: Observable.of({})} }, { provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => Observable.of(selectedValues), diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 8f71704a3e..b409082b4a 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -82,14 +82,18 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { this.filterValues$ = new BehaviorSubject(new RemoteData(true, false, undefined, undefined, undefined)); this.currentPage = this.getCurrentPage().distinctUntilChanged(); this.selectedValues = this.filterService.getSelectedValuesForFilter(this.filterConfig); - const searchOptions = this.searchConfigService.getSearchOptions().distinctUntilChanged(); - this.subs.push(searchOptions.subscribe((options) => this.updateFilterValueList())); - + const searchOptions = this.searchConfigService.searchOptions; + this.subs.push(this.searchConfigService.searchOptions.subscribe(() => this.updateFilterValueList())); const facetValues = Observable.combineLatest(searchOptions, this.currentPage, (options, page) => { - return { - values: this.searchService.getFacetValuesFor(this.filterConfig, page, options), - page: page - }; + return { options, page } + }).switchMap(({ options, page }) => { + return this.searchService.getFacetValuesFor(this.filterConfig, page, options).map((results) => { + return { + values: Observable.of(results), + page: page + }; + } + ); }); let filterValues = []; this.subs.push(facetValues.subscribe((facetOutcome) => { @@ -242,7 +246,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { */ findSuggestions(data): void { if (isNotEmpty(data)) { - this.searchConfigService.getSearchOptions().first().subscribe( + this.searchConfigService.searchOptions.first().subscribe( (options) => { this.filterSearchResults = this.searchService.getFacetValuesFor(this.filterConfig, 1, options, data.toLowerCase()) .first() diff --git a/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts b/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts index 739858c2f5..4e555459d6 100644 --- a/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts +++ b/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts @@ -74,7 +74,7 @@ describe('SearchRangeFilterComponent', () => { { provide: RemoteDataBuildService, useValue: {aggregate: () => Observable.of({})} }, { provide: RouteService, useValue: {getQueryParameterValue: () => Observable.of({})} }, { provide: SearchConfigurationService, useValue: { - getSearchOptions: () => Observable.of({}) } + searchOptions: Observable.of({}) } }, { provide: SearchFilterService, useValue: { diff --git a/src/app/+search-page/search-filters/search-filters.component.html b/src/app/+search-page/search-filters/search-filters.component.html index 566450b7f5..1e5c474d65 100644 --- a/src/app/+search-page/search-filters/search-filters.component.html +++ b/src/app/+search-page/search-filters/search-filters.component.html @@ -1,6 +1,6 @@

{{"search.filters.head" | translate}}

-
+
diff --git a/src/app/+search-page/search-page.component.spec.ts b/src/app/+search-page/search-page.component.spec.ts index a381c9c5d2..57b8caaddc 100644 --- a/src/app/+search-page/search-page.component.spec.ts +++ b/src/app/+search-page/search-page.component.spec.ts @@ -20,6 +20,7 @@ import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; import { SearchFilterService } from './search-filters/search-filter/search-filter.service'; import { SearchConfigurationService } from './search-service/search-configuration.service'; +import { RemoteData } from '../core/data/remote-data'; describe('SearchPageComponent', () => { let comp: SearchPageComponent; @@ -36,7 +37,7 @@ describe('SearchPageComponent', () => { pagination.currentPage = 1; pagination.pageSize = 10; const sort: SortOptions = new SortOptions('score', SortDirection.DESC); - const mockResults = Observable.of(['test', 'data']); + const mockResults = Observable.of(new RemoteData(false, false, true, null,['test', 'data'])); const searchServiceStub = jasmine.createSpyObj('SearchService', { search: mockResults, getSearchLink: '/search', @@ -45,11 +46,11 @@ describe('SearchPageComponent', () => { const queryParam = 'test query'; const scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f'; const paginatedSearchOptions = { - query: queryParam, - scope: scopeParam, - pagination, - sort - }; + query: queryParam, + scope: scopeParam, + pagination, + sort + }; const activatedRouteStub = { queryParams: Observable.of({ query: queryParam, @@ -91,17 +92,14 @@ describe('SearchPageComponent', () => { { provide: SearchFilterService, useValue: {} - },{ + }, { provide: SearchConfigurationService, - useValue: jasmine.createSpyObj('SearchConfigurationService', { - getPaginatedSearchOptions: hot('a', { + useValue: { + paginatedSearchOptions: hot('a', { a: paginatedSearchOptions }), - getCurrentScope: hot('a', { - a: 'test-id' - }), - - }) + getCurrentScope: (a) => Observable.of('test-id') + } }, ], schemas: [NO_ERRORS_SCHEMA] @@ -180,4 +178,5 @@ describe('SearchPageComponent', () => { }); }); -}); +}) +; diff --git a/src/app/+search-page/search-page.component.ts b/src/app/+search-page/search-page.component.ts index ad2a5a0fcd..52e59766d9 100644 --- a/src/app/+search-page/search-page.component.ts +++ b/src/app/+search-page/search-page.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { flatMap, } from 'rxjs/operators'; -import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model'; import { PaginatedList } from '../core/data/paginated-list'; import { RemoteData } from '../core/data/remote-data'; import { DSpaceObject } from '../core/shared/dspace-object.model'; @@ -77,11 +76,16 @@ export class SearchPageComponent implements OnInit { * If something changes, update the list of scopes for the dropdown */ ngOnInit(): void { - this.searchOptions$ = this.searchConfigService.getPaginatedSearchOptions(); - this.sub = this.searchOptions$.subscribe((searchOptions) => - this.service.search(searchOptions).filter((rd) => !rd.isLoading).first().subscribe((results) => this.resultsRD$.next(results))); - - this.scopeListRD$ = this.searchConfigService.getCurrentScope().pipe( + this.searchOptions$ = this.searchConfigService.paginatedSearchOptions; + let subscription; + this.sub = this.searchOptions$.subscribe((searchOptions) => { + if (hasValue(subscription)) { + /** Make sure no race condition is possible with a previous result coming back from the server later */ + subscription.unsubscribe(); + } + subscription = this.service.search(searchOptions).filter((rd) => !rd.isLoading).first().subscribe((results) => this.resultsRD$.next(results)) + }); + this.scopeListRD$ = this.searchConfigService.getCurrentScope('').pipe( flatMap((scopeId) => this.service.getScopes(scopeId)) ); } diff --git a/src/app/+search-page/search-service/search-configuration.service.spec.ts b/src/app/+search-page/search-service/search-configuration.service.spec.ts index a06edc482a..d7a41c4759 100644 --- a/src/app/+search-page/search-service/search-configuration.service.spec.ts +++ b/src/app/+search-page/search-service/search-configuration.service.spec.ts @@ -2,9 +2,12 @@ import { SearchConfigurationService } from './search-configuration.service'; import { Observable } from 'rxjs/Observable'; import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; import { RemoteData } from '../../core/data/remote-data'; -import { fakeAsync, tick } from '@angular/core/testing'; +import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; +import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; +import { PaginatedSearchOptions } from '../paginated-search-options.model'; +import { cold, hot } from 'jasmine-marbles'; -describe('SearchConfigurationService', () => { +fdescribe('SearchConfigurationService', () => { let service: SearchConfigurationService; const value1 = 'random value'; const value2 = 'another value'; @@ -13,13 +16,17 @@ describe('SearchConfigurationService', () => { 'f.date.min': ['2013'], 'f.date.max': ['2018'] }; - const defaults = Observable.of(new RemoteData(false, false, true, null, {})) + const defaults = Object.assign(new PaginatedSearchOptions(), { + pagination: Object.assign(new PaginationComponentOptions(), { currentPage: 1, pageSize: 20 }), + sort: new SortOptions('score', SortDirection.DESC), + query: '', + scope: '' + }); const backendFilters = { 'f.author': ['another value'], 'f.date': ['[2013 TO 2018]'] }; - const spy = jasmine.createSpyObj('SearchConfigurationService', { - getQueryParameterValue: Observable.of([value1, value2]) - , - getQueryParamsWithPrefix: Observable.of(prefixFilter) + const spy = jasmine.createSpyObj('RouteService', { + getQueryParameterValue: cold('a', {a: [value1, value2]}), + getQueryParamsWithPrefix: cold('a', {a: prefixFilter}), }); const activatedRoute: any = new ActivatedRouteStub(); @@ -28,9 +35,9 @@ describe('SearchConfigurationService', () => { service = new SearchConfigurationService(spy, activatedRoute); }); - describe('when getCurrentScope is called', () => { + describe('when the scope is called', () => { beforeEach(() => { - service.getCurrentScope(); + service.getCurrentScope(''); }); it('should call getQueryParameterValue on the routeService with parameter name \'scope\'', () => { expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('scope'); @@ -39,7 +46,7 @@ describe('SearchConfigurationService', () => { describe('when getCurrentQuery is called', () => { beforeEach(() => { - service.getCurrentQuery(); + service.getCurrentQuery(''); }); it('should call getQueryParameterValue on the routeService with parameter name \'query\'', () => { expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('query'); @@ -81,7 +88,7 @@ describe('SearchConfigurationService', () => { }); describe('when getCurrentPagination is called', () => { beforeEach(() => { - service.getCurrentPagination({}); + service.getCurrentPagination({ currentPage: 1, pageSize: 10 } as any); }); it('should call getQueryParameterValue on the routeService with parameter name \'page\'', () => { expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('page'); @@ -90,41 +97,38 @@ describe('SearchConfigurationService', () => { expect((service as any).routeService.getQueryParameterValue).toHaveBeenCalledWith('pageSize'); }); }); - fdescribe('when getPaginatedSearchOptions or getSearchOptions is called', () => { + fdescribe('when updateSearchOptions or updatePaginatedSearchOptions is called', () => { beforeEach(() => { - spyOn(service, 'getCurrentPagination'); - spyOn(service, 'getCurrentSort'); - spyOn(service, 'getCurrentScope'); - spyOn(service, 'getCurrentQuery'); - spyOn(service, 'getCurrentFilters'); + spyOn(service, 'getPaginationPart'); + spyOn(service, 'getSortPart'); + spyOn(service, 'getScopePart'); + spyOn(service, 'getQueryPart'); + spyOn(service, 'getFiltersPart'); }); describe('when getPaginatedSearchOptions is called', () => { beforeEach(() => { - service.getPaginatedSearchOptions(defaults); - }); - it('should call all getters it needs', fakeAsync(() => { - defaults.subscribe(() => { - tick(); - expect(service.getCurrentPagination).toHaveBeenCalled(); - expect(service.getCurrentSort).toHaveBeenCalled(); - expect(service.getCurrentScope).toHaveBeenCalled(); - expect(service.getCurrentQuery).toHaveBeenCalled(); - expect(service.getCurrentFilters).toHaveBeenCalled(); - } - ) - })); - }); - describe('when getSearchOptions is called', () => { - beforeEach(() => { - service.getSearchOptions(); + service.subscribeToSearchOptions(defaults); }); it('should call all getters it needs', () => { - expect(service.getCurrentPagination).not.toHaveBeenCalled(); - expect(service.getCurrentSort).not.toHaveBeenCalled(); - expect(service.getCurrentScope).toHaveBeenCalled(); - expect(service.getCurrentQuery).toHaveBeenCalled(); - expect(service.getCurrentFilters).toHaveBeenCalled(); + + // expect(service.getCurrentPagination).toHaveBeenCalled(); + // expect(service.getCurrentSort).toHaveBeenCalled(); + expect(service.getScopePart).toHaveBeenCalled(); + expect(service.getQueryPart).toHaveBeenCalled(); + expect(service.getFiltersPart).toHaveBeenCalled(); }); }); + // describe('when searchOptions is called', () => { + // beforeEach(() => { + // service.searchOptions; + // }); + // it('should call all getters it needs', () => { + // expect(service.getCurrentPagination).not.toHaveBeenCalled(); + // expect(service.getCurrentSort).not.toHaveBeenCalled(); + // expect(service.getCurrentScope).toHaveBeenCalled(); + // expect(service.getCurrentQuery).toHaveBeenCalled(); + // expect(service.getCurrentFilters).toHaveBeenCalled(); + // }); + // }); }); }); diff --git a/src/app/+search-page/search-service/search-configuration.service.ts b/src/app/+search-page/search-service/search-configuration.service.ts index b7cd43217c..6aeb856e87 100644 --- a/src/app/+search-page/search-service/search-configuration.service.ts +++ b/src/app/+search-page/search-service/search-configuration.service.ts @@ -5,53 +5,73 @@ import { distinctUntilChanged, map } from 'rxjs/operators'; import { Observable } from 'rxjs/Observable'; import { ActivatedRoute, Params } from '@angular/router'; import { PaginatedSearchOptions } from '../paginated-search-options.model'; -import { Injectable } from '@angular/core'; +import { Injectable, OnDestroy } from '@angular/core'; import { RouteService } from '../../shared/services/route.service'; import { hasNoValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; import { RemoteData } from '../../core/data/remote-data'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import { Subscription } from 'rxjs/Subscription'; /** * Service that performs all actions that have to do with the current search configuration */ @Injectable() -export class SearchConfigurationService { - private defaultPagination = { id: 'search-page-configuration', pageSize: 10 }; +export class SearchConfigurationService implements OnDestroy { + private defaultPagination = Object.assign(new PaginationComponentOptions(), { id: 'search-page-configuration', pageSize: 10, currentPage: 1 }); private defaultSort = new SortOptions('score', SortDirection.DESC); private defaultScope = ''; + private defaultQuery = ''; + private _defaults; + public searchOptions: BehaviorSubject; + public paginatedSearchOptions: BehaviorSubject; + private subs: Subscription[] = new Array(); + constructor(private routeService: RouteService, private route: ActivatedRoute) { + this.defaults.first().subscribe((defRD) => { + const defs = defRD.payload; + this.paginatedSearchOptions = new BehaviorSubject(defs); + this.searchOptions = new BehaviorSubject(defs); + this.subs.push(this.subscribeToSearchOptions(defs)); + this.subs.push(this.subscribeToPaginatedSearchOptions(defs)); + } + ) } /** * @returns {Observable} Emits the current scope's identifier */ - getCurrentScope() { - return this.routeService.getQueryParameterValue('scope'); + getCurrentScope(defaultScope: string) { + return this.routeService.getQueryParameterValue('scope').map((scope) => { + return scope || defaultScope; + }); } /** * @returns {Observable} Emits the current query string */ - getCurrentQuery() { - return this.routeService.getQueryParameterValue('query'); + getCurrentQuery(defaultQuery: string) { + return this.routeService.getQueryParameterValue('query').map((query) => { + return query || defaultQuery; + }); } /** * @returns {Observable} Emits the current pagination settings */ - getCurrentPagination(pagination: any = {}): Observable { + getCurrentPagination(defaultPagination: PaginationComponentOptions): Observable { const page$ = this.routeService.getQueryParameterValue('page'); const size$ = this.routeService.getQueryParameterValue('pageSize'); return Observable.combineLatest(page$, size$, (page, size) => { - return Object.assign(new PaginationComponentOptions(), pagination, { - currentPage: page || 1, - pageSize: size || pagination.pageSize + return Object.assign(new PaginationComponentOptions(), defaultPagination, { + currentPage: page || defaultPagination.currentPage, + pageSize: size || defaultPagination.pageSize }); }); } @@ -70,7 +90,7 @@ export class SearchConfigurationService { const direction = SortDirection[sortDirection] || defaultSort.direction; return new SortOptions(field, direction) } - ); + ) } /** @@ -98,77 +118,106 @@ export class SearchConfigurationService { }); } - /** + /** * @returns {Observable} Emits the current active filters with their values as they are displayed in the frontend URL */ getCurrentFrontendFilters(): Observable { return this.routeService.getQueryParamsWithPrefix('f.'); } - /** - * @param defaults The default values for the search options, that will be used if nothing is explicitly set - * @returns {Observable} Emits the current paginated search options - */ - getPaginatedSearchOptions(defaults: Observable> = this.defaults): Observable { - return defaults.flatMap((defaultConfig) => { - const defaultValues = defaultConfig.payload; - return Observable.combineLatest( - this.getCurrentPagination(defaultValues.pagination), - this.getCurrentSort(defaultValues.sort), - this.getCurrentScope(), - this.getCurrentQuery(), - this.getCurrentFilters()).pipe( - distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), - map(([pagination, sort, scope, query, filters]) => { - return Object.assign(new PaginatedSearchOptions(), - defaults, - { - pagination: pagination, - sort: sort, - scope: scope || defaultValues.scope, - query: query, - filters: filters - }) - }) - ) + subscribeToSearchOptions(defaults: SearchOptions): Subscription { + console.log('scope: ', this.getScopePart(defaults.scope)); + console.log('query: ', this.getQueryPart(defaults.query)); + console.log('filters: ', this.getFiltersPart()); + this.getScopePart(defaults.scope).subscribe((y) => console.log('scope: ' + JSON.stringify(y))); + this.getQueryPart(defaults.query).subscribe((y) => console.log('query: ' + JSON.stringify(y))); + this.getFiltersPart().subscribe((y) => console.log('filters: ' + JSON.stringify(y))); + return Observable.merge( + this.getScopePart(defaults.scope), + this.getQueryPart(defaults.query), + this.getFiltersPart() + ).subscribe((update) => { + const currentValue: SearchOptions = this.searchOptions.getValue(); + const updatedValue: SearchOptions = Object.assign(new SearchOptions(), currentValue, update); + this.searchOptions.next(updatedValue); }); } - /** - * @param defaults The default values for the search options, that will be used if nothing is explicitly set - * @returns {Observable} Emits the current search options - */ - getSearchOptions(defaults: Observable> = this.defaults): Observable { - return defaults.flatMap((defaultConfig) => { - const defaultValues = defaultConfig.payload; - return Observable.combineLatest( - this.getCurrentScope(), - this.getCurrentQuery(), - this.getCurrentFilters(), - (scope, query, filters) => { - return Object.assign(new SearchOptions(), - { - scope: scope || defaultValues.scope, - query: query, - filters: filters - }) - } - ) + subscribeToPaginatedSearchOptions(defaults: PaginatedSearchOptions): Subscription { + return Observable.merge( + this.getPaginationPart(defaults.pagination), + this.getSortPart(defaults.sort), + this.getScopePart(defaults.scope), + this.getQueryPart(defaults.query), + this.getFiltersPart() + ).subscribe((update) => { + const currentValue: PaginatedSearchOptions = this.paginatedSearchOptions.getValue(); + const updatedValue: PaginatedSearchOptions = Object.assign(new PaginatedSearchOptions(), currentValue, update); + this.paginatedSearchOptions.next(updatedValue); }); } /** * Default values for the Search Options */ - get defaults() { + get defaults(): Observable> { if (hasNoValue(this._defaults)) { - const options = { + const options = Object.assign(new PaginatedSearchOptions(), { pagination: this.defaultPagination, sort: this.defaultSort, - scope: this.defaultScope - }; + scope: this.defaultScope, + query: this.defaultQuery + }); this._defaults = Observable.of(new RemoteData(false, false, true, null, options)); } return this._defaults; } + + ngOnDestroy(): void { + this.subs.forEach((sub) => { + sub.unsubscribe(); + }); + } + + getScopePart(defaultScope: string): Observable { + return this.getCurrentScope(defaultScope).map((scope) => { + return { scope } + }); + } + + /** + * @returns {Observable} Emits the current query string + */ + getQueryPart(defaultQuery: string): Observable { + return this.getCurrentQuery(defaultQuery).map((query) => { + return { query } + }); + } + + /** + * @returns {Observable} Emits the current pagination settings + */ + getPaginationPart(defaultPagination: PaginationComponentOptions): Observable { + return this.getCurrentPagination(defaultPagination).map((pagination) => { + return { pagination } + }); + } + + /** + * @returns {Observable} Emits the current sorting settings + */ + getSortPart(defaultSort: SortOptions): Observable { + return this.getCurrentSort(defaultSort).map((sort) => { + return { sort } + }); + } + + /** + * @returns {Observable} Emits the current active filters with their values as they are sent to the backend + */ + getFiltersPart(): Observable { + return this.getCurrentFilters().map((filters) => { + return { filters } + }); + } } diff --git a/src/app/+search-page/search-settings/search-settings.component.spec.ts b/src/app/+search-page/search-settings/search-settings.component.spec.ts index 898af1c2d7..5e6dc9b369 100644 --- a/src/app/+search-page/search-settings/search-settings.component.spec.ts +++ b/src/app/+search-page/search-settings/search-settings.component.spec.ts @@ -73,15 +73,14 @@ describe('SearchSettingsComponent', () => { }, { provide: SearchConfigurationService, - useValue: jasmine.createSpyObj('SearchConfigurationService', { - getPaginatedSearchOptions: hot('a', { + useValue: { + paginatedSearchOptions: hot('a', { a: paginatedSearchOptions }), getCurrentScope: hot('a', { a: 'test-id' }), - - }) + } }, ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/+search-page/search-settings/search-settings.component.ts b/src/app/+search-page/search-settings/search-settings.component.ts index f175c1a871..81e2366e39 100644 --- a/src/app/+search-page/search-settings/search-settings.component.ts +++ b/src/app/+search-page/search-settings/search-settings.component.ts @@ -38,7 +38,7 @@ export class SearchSettingsComponent implements OnInit { * Initialize paginated search options */ ngOnInit(): void { - this.searchOptions$ = this.searchConfigurationService.getPaginatedSearchOptions(); + this.searchOptions$ = this.searchConfigurationService.paginatedSearchOptions; } /** @@ -50,6 +50,7 @@ export class SearchSettingsComponent implements OnInit { const navigationExtras: NavigationExtras = { queryParams: { pageSize: value, + page: 1 }, queryParamsHandling: 'merge' }; @@ -65,7 +66,8 @@ export class SearchSettingsComponent implements OnInit { const navigationExtras: NavigationExtras = { queryParams: { sortDirection: values[1], - sortField: values[0] + sortField: values[0], + page: 1 }, queryParamsHandling: 'merge' }; diff --git a/src/app/shared/services/route.service.ts b/src/app/shared/services/route.service.ts index aa683a6403..4b237d7930 100644 --- a/src/app/shared/services/route.service.ts +++ b/src/app/shared/services/route.service.ts @@ -17,6 +17,7 @@ export class RouteService { } getQueryParameterValue(paramName: string): Observable { + this.route.queryParamMap.map((map) => map.get(paramName)).distinctUntilChanged().subscribe((t) => console.log('paramName: ' + paramName + 'values: ' + t)); return this.route.queryParamMap.map((map) => map.get(paramName)).distinctUntilChanged(); } @@ -38,6 +39,7 @@ export class RouteService { params[key] = [...map.getAll(key)]; }); return params; - }).distinctUntilChanged(); + }) + .distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)); } } diff --git a/src/app/shared/testing/active-router-stub.ts b/src/app/shared/testing/active-router-stub.ts index 35c966d72a..22c4060855 100644 --- a/src/app/shared/testing/active-router-stub.ts +++ b/src/app/shared/testing/active-router-stub.ts @@ -21,7 +21,10 @@ export class ActivatedRouteStub { } // Test parameters - get testParams() { return this._testParams; } + get testParams() { + return this._testParams; + } + set testParams(params: {}) { this._testParams = params; this.subject.next(params); @@ -29,6 +32,9 @@ export class ActivatedRouteStub { // ActivatedRoute.snapshot.params get snapshot() { - return { params: this.testParams }; + return { + params: this.testParams, + queryParamMap: convertToParamMap(this.testParams) + } } }