diff --git a/resources/i18n/en.json5 b/resources/i18n/en.json5 index 8d956d1a0e..044cf216b8 100644 --- a/resources/i18n/en.json5 +++ b/resources/i18n/en.json5 @@ -266,6 +266,8 @@ "collection.edit.head": "Edit Collection", + "collection.edit.breadcrumbs": "Edit Collection", + "collection.edit.item-mapper.cancel": "Cancel", @@ -450,6 +452,7 @@ "community.edit.head": "Edit Community", + "community.edit.breadcrumbs": "Edit Community", "community.edit.logo.label": "Community logo", @@ -657,6 +660,8 @@ "item.edit.head": "Edit Item", + "item.edit.breadcrumbs": "Edit Item", + "item.edit.item-mapper.buttons.add": "Map item to selected collections", @@ -1077,6 +1082,8 @@ "login.title": "Login", + "login.breadcrumbs": "Login", + "logout.form.header": "Log out from DSpace", @@ -1473,6 +1480,7 @@ "search.title": "DSpace Angular :: Search", + "search.breadcrumbs": "Search", "search.filters.applied.f.author": "Author", diff --git a/src/app/+collection-page/collection-page-routing.module.ts b/src/app/+collection-page/collection-page-routing.module.ts index 4bd23f4f95..61cfda0d9e 100644 --- a/src/app/+collection-page/collection-page-routing.module.ts +++ b/src/app/+collection-page/collection-page-routing.module.ts @@ -21,7 +21,7 @@ export function getCollectionPageRoute(collectionId: string) { } export function getCollectionEditPath(id: string) { - return new URLCombiner(getCollectionModulePath(), COLLECTION_EDIT_PATH.replace(/:id/, id)).toString() + return new URLCombiner(getCollectionModulePath(), id, COLLECTION_EDIT_PATH).toString() } export function getCollectionCreatePath() { diff --git a/src/app/+collection-page/edit-collection-page/edit-collection-page.routing.module.ts b/src/app/+collection-page/edit-collection-page/edit-collection-page.routing.module.ts index 4498198e8d..e3d5749472 100644 --- a/src/app/+collection-page/edit-collection-page/edit-collection-page.routing.module.ts +++ b/src/app/+collection-page/edit-collection-page/edit-collection-page.routing.module.ts @@ -5,6 +5,7 @@ import { CollectionMetadataComponent } from './collection-metadata/collection-me import { CollectionRolesComponent } from './collection-roles/collection-roles.component'; import { CollectionSourceComponent } from './collection-source/collection-source.component'; import { CollectionCurateComponent } from './collection-curate/collection-curate.component'; +import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; /** * Routing module that handles the routing for the Edit Collection page administrator functionality @@ -14,6 +15,10 @@ import { CollectionCurateComponent } from './collection-curate/collection-curate RouterModule.forChild([ { path: '', + resolve: { + breadcrumb: I18nBreadcrumbResolver + }, + data: { breadcrumbKey: 'collection.edit' }, component: EditCollectionPageComponent, children: [ { diff --git a/src/app/+community-page/community-page-routing.module.ts b/src/app/+community-page/community-page-routing.module.ts index 7ee71034a6..976a4ad0fe 100644 --- a/src/app/+community-page/community-page-routing.module.ts +++ b/src/app/+community-page/community-page-routing.module.ts @@ -20,7 +20,7 @@ export function getCommunityPageRoute(communityId: string) { } export function getCommunityEditPath(id: string) { - return new URLCombiner(getCommunityModulePath(), COMMUNITY_EDIT_PATH.replace(/:id/, id)).toString() + return new URLCombiner(getCommunityModulePath(), id, COMMUNITY_EDIT_PATH).toString() } export function getCommunityCreatePath() { diff --git a/src/app/+community-page/edit-community-page/edit-community-page.routing.module.ts b/src/app/+community-page/edit-community-page/edit-community-page.routing.module.ts index 721a404f84..f0a7813bac 100644 --- a/src/app/+community-page/edit-community-page/edit-community-page.routing.module.ts +++ b/src/app/+community-page/edit-community-page/edit-community-page.routing.module.ts @@ -5,6 +5,7 @@ import { NgModule } from '@angular/core'; import { CommunityMetadataComponent } from './community-metadata/community-metadata.component'; import { CommunityRolesComponent } from './community-roles/community-roles.component'; import { CommunityCurateComponent } from './community-curate/community-curate.component'; +import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; /** * Routing module that handles the routing for the Edit Community page administrator functionality @@ -14,6 +15,10 @@ import { CommunityCurateComponent } from './community-curate/community-curate.co RouterModule.forChild([ { path: '', + resolve: { + breadcrumb: I18nBreadcrumbResolver + }, + data: { breadcrumbKey: 'community.edit' }, component: EditCommunityPageComponent, children: [ { diff --git a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts index 71d8f65568..af78eeea6f 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts @@ -33,7 +33,7 @@ const ITEM_EDIT_MOVE_PATH = 'move'; resolve: { breadcrumb: I18nBreadcrumbResolver }, - data: { breadcrumbKey: 'edit.item' }, + data: { breadcrumbKey: 'item.edit' }, children: [ { path: '', diff --git a/src/app/+item-page/item-page-routing.module.ts b/src/app/+item-page/item-page-routing.module.ts index 4ceece59d0..686c5ff2fc 100644 --- a/src/app/+item-page/item-page-routing.module.ts +++ b/src/app/+item-page/item-page-routing.module.ts @@ -16,7 +16,7 @@ export function getItemPageRoute(itemId: string) { } export function getItemEditPath(id: string) { - return new URLCombiner(getItemModulePath(), ITEM_EDIT_PATH.replace(/:id/, id)).toString() + return new URLCombiner(getItemModulePath(), id, ITEM_EDIT_PATH).toString() } const ITEM_EDIT_PATH = 'edit'; diff --git a/src/app/+login-page/login-page-routing.module.ts b/src/app/+login-page/login-page-routing.module.ts index 950ac44d8c..cd023da55c 100644 --- a/src/app/+login-page/login-page-routing.module.ts +++ b/src/app/+login-page/login-page-routing.module.ts @@ -7,7 +7,7 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso @NgModule({ imports: [ RouterModule.forChild([ - { path: '', pathMatch: 'full', component: LoginPageComponent, resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { breadcrumbKey: 'Search', title: 'login.title' } } + { path: '', pathMatch: 'full', component: LoginPageComponent, resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { breadcrumbKey: 'login', title: 'login.title' } } ]) ] }) diff --git a/src/app/+search-page/search-page-routing.module.ts b/src/app/+search-page/search-page-routing.module.ts index c76207da9b..6e36883394 100644 --- a/src/app/+search-page/search-page-routing.module.ts +++ b/src/app/+search-page/search-page-routing.module.ts @@ -11,7 +11,7 @@ import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.ser imports: [ RouterModule.forChild([{ path: '', - resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { title: 'search.title', breadcrumbKey: 'Search' }, + resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { title: 'search.title', breadcrumbKey: 'search' }, children: [ { path: '', component: SearchPageComponent }, { path: ':configuration', component: ConfigurationSearchPageComponent, canActivate: [ConfigurationSearchPageGuard] } diff --git a/src/app/breadcrumbs/breadcrumbs.component.spec.ts b/src/app/breadcrumbs/breadcrumbs.component.spec.ts index 175ef83757..0ab1fed208 100644 --- a/src/app/breadcrumbs/breadcrumbs.component.spec.ts +++ b/src/app/breadcrumbs/breadcrumbs.component.spec.ts @@ -1,25 +1,111 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { BreadcrumbsComponent } from './breadcrumbs.component'; +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; +import { Observable, of as observableOf } from 'rxjs'; +import { RouterTestingModule } from '@angular/router/testing'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { MockTranslateLoader } from '../shared/testing/mock-translate-loader'; +import { BreadcrumbConfig } from './breadcrumb/breadcrumb-config.model'; +import { BreadcrumbsService } from '../core/breadcrumbs/breadcrumbs.service'; +import { Breadcrumb } from './breadcrumb/breadcrumb.model'; +import { getTestScheduler } from 'jasmine-marbles'; + +class TestBreadcrumbsService implements BreadcrumbsService { + getBreadcrumbs(key: string, url: string): Observable { + return observableOf([new Breadcrumb(key, url)]); + } +} describe('BreadcrumbsComponent', () => { let component: BreadcrumbsComponent; let fixture: ComponentFixture; + let router: any; + let route: any; + let breadcrumbProvider; + let breadcrumbConfigA: BreadcrumbConfig; + let breadcrumbConfigB: BreadcrumbConfig; + let expectedBreadcrumbs; + + function init() { + breadcrumbProvider = new TestBreadcrumbsService(); + + breadcrumbConfigA = { provider: breadcrumbProvider, key: 'example.path', url: 'example.com' }; + breadcrumbConfigB = { provider: breadcrumbProvider, key: 'another.path', url: 'another.com' }; + + route = { + root: { + snapshot: { + data: { breadcrumb: breadcrumbConfigA }, + routeConfig: { resolve: { breadcrumb: {} } } + }, + firstChild: { + snapshot: { + // Example without resolver should be ignored + data: { breadcrumb: breadcrumbConfigA }, + }, + firstChild: { + snapshot: { + data: { breadcrumb: breadcrumbConfigB }, + routeConfig: { resolve: { breadcrumb: {} } } + } + } + } + } + }; + + expectedBreadcrumbs = [ + new Breadcrumb(breadcrumbConfigA.key, breadcrumbConfigA.url), + new Breadcrumb(breadcrumbConfigB.key, breadcrumbConfigB.url) + ] + + } beforeEach(async(() => { + init(); TestBed.configureTestingModule({ - declarations: [ BreadcrumbsComponent ] + declarations: [BreadcrumbsComponent], + imports: [RouterTestingModule.withRoutes([]), TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: MockTranslateLoader + } + })], + providers: [ + { provide: ActivatedRoute, useValue: route } + + ] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(BreadcrumbsComponent); component = fixture.componentInstance; + router = TestBed.get(Router); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + describe('ngOnInit', () => { + beforeEach(() => { + spyOn(component, 'resolveBreadcrumbs').and.returnValue(observableOf([])) + }); + + it('should call resolveBreadcrumb on init', () => { + router.events = observableOf(new NavigationEnd(0, '', '')); + component.ngOnInit(); + expect(component.resolveBreadcrumbs).toHaveBeenCalledWith(route.root); + }) + }); + + describe('resolveBreadcrumbs', () => { + it('should return the correct breadcrumbs', () => { + const breadcrumbs = component.resolveBreadcrumbs(route.root); + getTestScheduler().expectObservable(breadcrumbs).toBe('(a|)', { a: expectedBreadcrumbs }) + }) + }) }); diff --git a/src/app/breadcrumbs/breadcrumbs.component.ts b/src/app/breadcrumbs/breadcrumbs.component.ts index fc3527a241..19b77fe59c 100644 --- a/src/app/breadcrumbs/breadcrumbs.component.ts +++ b/src/app/breadcrumbs/breadcrumbs.component.ts @@ -1,17 +1,16 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { Breadcrumb } from './breadcrumb/breadcrumb.model'; -import { hasValue, isNotUndefined } from '../shared/empty.util'; +import { hasNoValue, hasValue, isNotUndefined } from '../shared/empty.util'; import { filter, map, switchMap, tap } from 'rxjs/operators'; import { combineLatest, Observable, Subscription, of as observableOf } from 'rxjs'; -import { BreadcrumbConfig } from './breadcrumb/breadcrumb-config.model'; @Component({ selector: 'ds-breadcrumbs', templateUrl: './breadcrumbs.component.html', styleUrls: ['./breadcrumbs.component.scss'] }) -export class BreadcrumbsComponent implements OnDestroy { +export class BreadcrumbsComponent implements OnInit, OnDestroy { breadcrumbs: Breadcrumb[]; showBreadcrumbs: boolean; subscription: Subscription; @@ -20,21 +19,24 @@ export class BreadcrumbsComponent implements OnDestroy { private route: ActivatedRoute, private router: Router ) { + } + + ngOnInit(): void { this.subscription = this.router.events.pipe( filter((e): e is NavigationEnd => e instanceof NavigationEnd), tap(() => this.reset()), - switchMap(() => this.resolveBreadcrumb(this.route.root)) + switchMap(() => this.resolveBreadcrumbs(this.route.root)) ).subscribe((breadcrumbs) => { this.breadcrumbs = breadcrumbs; } ) } - resolveBreadcrumb(route: ActivatedRoute): Observable { + resolveBreadcrumbs(route: ActivatedRoute): Observable { const data = route.snapshot.data; const routeConfig = route.snapshot.routeConfig; - const last: boolean = route.children.length === 0; + const last: boolean = hasNoValue(route.firstChild); if (last && isNotUndefined(data.showBreadcrumbs)) { this.showBreadcrumbs = data.showBreadcrumbs; } @@ -45,13 +47,13 @@ export class BreadcrumbsComponent implements OnDestroy { ) { const { provider, key, url } = data.breadcrumb; if (!last) { - return combineLatest(provider.getBreadcrumbs(key, url), this.resolveBreadcrumb(route.firstChild)) + return combineLatest(provider.getBreadcrumbs(key, url), this.resolveBreadcrumbs(route.firstChild)) .pipe(map((crumbs) => [].concat.apply([], crumbs))); } else { return provider.getBreadcrumbs(key, url); } } - return !last ? this.resolveBreadcrumb(route.firstChild) : observableOf([]); + return !last ? this.resolveBreadcrumbs(route.firstChild) : observableOf([]); } ngOnDestroy(): void { diff --git a/src/app/core/breadcrumbs/collection-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/collection-breadcrumb.resolver.ts index ec48e89421..78f90f149a 100644 --- a/src/app/core/breadcrumbs/collection-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/collection-breadcrumb.resolver.ts @@ -1,7 +1,5 @@ import { Injectable } from '@angular/core'; import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; -import { ItemDataService } from '../data/item-data.service'; -import { Item } from '../shared/item.model'; import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; import { Collection } from '../shared/collection.model'; import { CollectionDataService } from '../data/collection-data.service'; diff --git a/src/app/core/breadcrumbs/dso-breadcrumbs.service.spec.ts b/src/app/core/breadcrumbs/dso-breadcrumbs.service.spec.ts new file mode 100644 index 0000000000..dc6195071a --- /dev/null +++ b/src/app/core/breadcrumbs/dso-breadcrumbs.service.spec.ts @@ -0,0 +1,117 @@ +import { async, TestBed } from '@angular/core/testing'; +import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; +import { getMockLinkService } from '../../shared/mocks/mock-link-service'; +import { LinkService } from '../cache/builders/link.service'; +import { Item } from '../shared/item.model'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils'; +import { DSpaceObject } from '../shared/dspace-object.model'; +import { map } from 'rxjs/operators'; +import { of as observableOf } from 'rxjs'; +import { RemoteData } from '../data/remote-data'; +import { hasValue } from '../../shared/empty.util'; +import { Community } from '../shared/community.model'; +import { Collection } from '../shared/collection.model'; +import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model'; +import { getItemPageRoute } from '../../+item-page/item-page-routing.module'; +import { getCommunityPageRoute } from '../../+community-page/community-page-routing.module'; +import { getCollectionPageRoute } from '../../+collection-page/collection-page-routing.module'; +import { cold, getTestScheduler } from 'jasmine-marbles'; +import { getDSOPath } from '../../app-routing.module'; + +fdescribe('DSOBreadcrumbsService', () => { + let service: DSOBreadcrumbsService; + let linkService: any; + let testItem; + let testCollection; + let testCommunity; + + let itemPath; + let collectionPath; + let communityPath; + + let itemUUID; + let collectionUUID; + let communityUUID; + + let objects: DSpaceObject[]; + + function init() { + itemPath = '/items/'; + collectionPath = '/collection/'; + communityPath = '/community/'; + + itemUUID = '04dd18fc-03f9-4b9a-9304-ed7c313686d3'; + collectionUUID = '91dfa5b5-5440-4fb4-b869-02610342f886'; + communityUUID = '6c0bfa6b-ce82-4bf4-a2a8-fd7682c567e8'; + + testCommunity = Object.assign(new Community(), + { + type: 'community', + name: 'community', + uuid: communityUUID, + parentCommunity: observableOf(Object.assign(createSuccessfulRemoteDataObject(undefined), { statusCode: 204 })), + + _links: { + parentCommunity: 'site', + self: communityPath + communityUUID + } + } + ); + + testCollection = Object.assign(new Collection(), + { + type: 'collection', + name: 'collection', + uuid: collectionUUID, + parentCommunity: createSuccessfulRemoteDataObject$(testCommunity), + _links: { + parentCommunity: communityPath + communityUUID, + self: communityPath + collectionUUID + } + } + ); + + testItem = Object.assign(new Item(), + { + type: 'item', + name: 'item', + uuid: itemUUID, + owningCollection: createSuccessfulRemoteDataObject$(testCollection), + _links: { + owningCollection: collectionPath + collectionUUID, + self: itemPath + itemUUID + } + } + ); + + objects = [testItem, testCollection, testCommunity]; + + } + + beforeEach(async(() => { + init(); + TestBed.configureTestingModule({ + providers: [ + { provide: LinkService, useValue: getMockLinkService() } + ] + }).compileComponents(); + })); + + beforeEach(() => { + linkService = TestBed.get(LinkService); + linkService.resolveLink.and.callFake((object, link) => object); + service = new DSOBreadcrumbsService(linkService); + }); + + describe('getBreadcrumbs', () => { + it('should return the breadcrumbs based on an Item', () => { + const breadcrumbs = service.getBreadcrumbs(testItem, testItem._links.self); + const expectedCrumbs = [ + new Breadcrumb(testCommunity.name, getDSOPath(testCommunity)), + new Breadcrumb(testCollection.name, getDSOPath(testCollection)), + new Breadcrumb(testItem.name, getDSOPath(testItem)), + ]; + getTestScheduler().expectObservable(breadcrumbs).toBe('(a|)', { a: expectedCrumbs }); + }) + }); +}); diff --git a/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts b/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts index eaf1fed759..e4a22f1bf5 100644 --- a/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts +++ b/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts @@ -26,11 +26,11 @@ export class DSOBreadcrumbsService implements BreadcrumbsService) => childRD.hasSucceeded || childRD.statusCode === 204), - switchMap((childRD: RemoteData) => { - if (hasValue(childRD.payload)) { - const child = childRD.payload; - return this.getBreadcrumbs(child, getDSOPath(child)) + find((parentRD: RemoteData) => parentRD.hasSucceeded || parentRD.statusCode === 204), + switchMap((parentRD: RemoteData) => { + if (hasValue(parentRD.payload)) { + const parent = parentRD.payload; + return this.getBreadcrumbs(parent, getDSOPath(parent)) } return observableOf([]); diff --git a/src/app/core/breadcrumbs/i18n-breadcrumbs.service.spec.ts b/src/app/core/breadcrumbs/i18n-breadcrumbs.service.spec.ts new file mode 100644 index 0000000000..f29907312b --- /dev/null +++ b/src/app/core/breadcrumbs/i18n-breadcrumbs.service.spec.ts @@ -0,0 +1,31 @@ +import { async, TestBed } from '@angular/core/testing'; +import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model'; +import { getTestScheduler } from 'jasmine-marbles'; +import { BREADCRUMB_MESSAGE_POSTFIX, I18nBreadcrumbsService } from './i18n-breadcrumbs.service'; + +fdescribe('I18nBreadcrumbsService', () => { + let service: I18nBreadcrumbsService; + let exampleString; + let exampleURL; + + function init() { + exampleString = 'example.string'; + exampleURL = 'example.com'; + } + + beforeEach(async(() => { + init(); + TestBed.configureTestingModule({}).compileComponents(); + })); + + beforeEach(() => { + service = new I18nBreadcrumbsService(); + }); + + describe('getBreadcrumbs', () => { + it('should return a breadcrumb based on a string by adding the postfix', () => { + const breadcrumbs = service.getBreadcrumbs(exampleString, exampleURL); + getTestScheduler().expectObservable(breadcrumbs).toBe('(a|)', { a: [new Breadcrumb(exampleString + BREADCRUMB_MESSAGE_POSTFIX, exampleURL)] }); + }) + }); +}); diff --git a/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts b/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts index 6a9c8916a2..97ff89479a 100644 --- a/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts +++ b/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts @@ -3,11 +3,11 @@ import { BreadcrumbsService } from './breadcrumbs.service'; import { Observable, of as observableOf } from 'rxjs'; import { Injectable } from '@angular/core'; -export const BREADCRUMB_MESSAGE_PREFIX = 'breadcrumbs.'; +export const BREADCRUMB_MESSAGE_POSTFIX = '.breadcrumbs'; @Injectable() export class I18nBreadcrumbsService implements BreadcrumbsService { getBreadcrumbs(key: string, url: string): Observable { - return observableOf([new Breadcrumb(BREADCRUMB_MESSAGE_PREFIX + key, url)]); + return observableOf([new Breadcrumb(key + BREADCRUMB_MESSAGE_POSTFIX, url)]); } } diff --git a/src/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts b/src/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts index 1bc83d74a5..091e02723f 100644 --- a/src/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts +++ b/src/app/shared/comcol-page-browse-by/comcol-page-browse-by.component.ts @@ -12,7 +12,7 @@ import { filter, map, startWith, tap } from 'rxjs/operators'; import { getCollectionPageRoute } from '../../+collection-page/collection-page-routing.module'; import { getCommunityPageRoute } from '../../+community-page/community-page-routing.module'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; -import { Router, ActivatedRoute, RouterModule, UrlSegment } from '@angular/router'; +import { Router, ActivatedRoute, RouterModule, UrlSegment, Params } from '@angular/router'; import { BrowseByTypeConfig } from '../../../config/browse-by-type-config.interface'; import { hasValue } from '../empty.util'; @@ -76,9 +76,8 @@ export class ComcolPageBrowseByComponent implements OnInit { }, ...this.allOptions ]; } - this.currentOptionId$ = this.route.url.pipe( - filter((urlSegments: UrlSegment[]) => hasValue(urlSegments)), - map((urlSegments: UrlSegment[]) => urlSegments[urlSegments.length - 1].path) + this.currentOptionId$ = this.route.params.pipe( + map((params: Params) => params.id) ); }