Skip to content

Instantly share code, notes, and snippets.

@pniel-cohen
Forked from katowulf/app.component.ts
Last active November 18, 2019 20:18
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save pniel-cohen/2303195c240add54ae8ce68d78e0fe03 to your computer and use it in GitHub Desktop.
Save pniel-cohen/2303195c240add54ae8ce68d78e0fe03 to your computer and use it in GitHub Desktop.
Dynamically set page title based on active route in Angular 4
import ...
@NgModule({
...
providers: [ TitleService ],
})
export class AppModule {
constructor(titleService: TitleService) {
titleService.init();
}
}
// If a route is declared with a title attribute, it gets used, otherwise we just try to parse the url fragment
// Here's where the title attribute goes
const routes: Routes = [{
path: '',
component: HomeComponent,
data: {title: "My Home Page"},
}, {
path: 'detail/:id',
component: DetailComponent,
}];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ExampleRoutingModule {
}
// Credits and thanks:
// https://toddmotto.com/dynamic-page-titles-angular-2-router-events
// https://stackoverflow.com/questions/34597835/how-to-get-current-route
//
import { Injectable } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, map, switchMap } from 'rxjs/operators';
const APP_TITLE = 'NoDice!';
const SEPARATOR = ' > ';
@Injectable()
export class TitleService {
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private titleService: Title,
) {}
init() {
this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map(route => route.firstChild),
switchMap(route => route.data),
map((data) => {
if (data.title) {
// If a route has a title set (e.g. data: {title: "Foo"}) then we use it
return data.title;
} else {
// If not, we do a little magic on the url to create an approximation
return this.router.url.split('/').reduce((acc, frag) => {
if (acc && frag) { acc += SEPARATOR; }
return this.router.url.split('/').reduce((acc, frag) => {
if ( acc && frag ) { acc += SEPARATOR; }
return acc + TitleService.ucFirst(frag);
});
});
}
})
)
.subscribe((pathString) => this.titleService.setTitle(`${APP_TITLE} ${pathString}`));
}
static ucFirst(string) {
if ( !string ) { return string; }
return string.charAt(0).toUpperCase() + string.slice(1);
}
}
@mstfe
Copy link

mstfe commented Aug 16, 2018

Hi,
Please change this code line. if have children title
map(route => route.firstChild), --->
map((route) => {
while (route.firstChild) route = route.firstChild;
return route;
}),

@LancelotSaki
Copy link

Thank you!!!

@BartusZak
Copy link

BartusZak commented Nov 28, 2018

[tslint] Declaration of static method not allowed after declaration of instance method. Instead, this should come at the beginning of the class/interface. [member-ordering]

For a better code performance we should declare static methods before init() method.

@novaDev315
Copy link

worked fine, Thank you

Copy link

ghost commented Feb 7, 2019

working Good ..thanks

@hadi-aj
Copy link

hadi-aj commented Mar 18, 2019

Not working, Angular 7 and nested routing.
i use this: https://github.com/angular/angular/issues/19420#issuecomment-333071573

...
map(() => {
    let route = this.activatedRoute.firstChild;
    let child = route;
    while (child) {
        if (child.firstChild) {
            child = child.firstChild;
            route = child;
        } else {
            child = null;
        }
    }
    return route;
}),
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment