14

In my app Im trying to dynamically change the title in my header component depending on the page that Im on, so In my header component I want to use a

<h1>{{title}}</h1>

and I want it to change depending on the page that I am on. Now the header is fixed so it's on every page

below is an image of what im trying to change enter image description here

Basically if im on the home page I want it to say home and then if Im on an about page I want it to change to about..

Not sure how I can go about this and everything ive researched has been to change the title in the <head></head> tags

Smokey Dawson
  • 7,596
  • 15
  • 68
  • 133

5 Answers5

25

You can create a service dedicated for updating the title in your header component. Simply inject the service in your header component and subscribe to a dedicated BehaviorSubject. Then you can inject this service in any component you have and use the setTitle method from that component which will update the title in the header component. Check out the following code

//headerTitle.service.ts
@Injectable()
export class headerTitleService {
  title = new BehaviorSubject('Initial Title');

  setTitle(title: string) {
    this.title.next(title);
  }
}

//header.component.ts
title = '';

constructor(private headerTitleService: HeaderTitleService) {}

ngOnInit() {
  this.headerTitleService.title.subscribe(updatedTitle => {
    this.title = updatedTitle;
  });
}

//header.component.html
<h1>{{title}}</h1>

//about.component.ts
constructor(private headerTitleService: HeaderTitleService) {}

ngOnInit() {
  this.headerTitleService.setTitle('About');
}

Working demo

Aamir Khan
  • 2,777
  • 2
  • 24
  • 31
2

Use the title service in @angular/platform-browser and add router component with data property.

const appRoutes: Routes = [
  { path: 'home',component:HomeComponent , data:{title:'Home'}}

  ];

Call this function in the root component

ngOnInit() {
    this.router.events
      .filter((event) => event instanceof NavigationEnd)
      .map(() => this.activatedRoute)
      .map((route) => {
        while (route.firstChild) route = route.firstChild;
        return route;
      })
      .filter((route) => route.outlet === 'primary')
      .mergeMap((route) => route.data)
      .subscribe((event) => this.titleService.setTitle(event['title']));
  }
}
0

use title service in browser platform to change the title dynamically. refer this link for more information

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule, Title }  from '@angular/platform-browser';

import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule
  ],
  declarations: [
    AppComponent
  ],
  providers: [
    Title
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

app.component.ts

// Import the native Angular services.
import { Component } from '@angular/core';
import { Title }     from '@angular/platform-browser';

@Component({
selector: 'app-root',
template:
  `<p>
    Select a title to set on the current HTML document:
  </p>

  <ul>
    <li><a (click)="setTitle( 'Good morning!' )">Good morning</a>.</li>
    <li><a (click)="setTitle( 'Good afternoon!' )">Good afternoon</a>.</li>
    <li><a (click)="setTitle( 'Good evening!' )">Good evening</a>.</li>
  </ul>
  `
})
export class AppComponent {
  public constructor(private titleService: Title ) { }

  public setTitle( newTitle: string) {
    this.titleService.setTitle( newTitle );
  }
}
Prithivi Raj
  • 2,568
  • 1
  • 17
  • 32
0

Based on OP's requirement, it seems OP needs to bind a string property to the page.

In your component have a property. Since its a fix string you can initialize it on each component like:

 public title:string = 'About me';

and in your HTML just:

<h1>{{title}}</h1>

Update:

Since it is to be bound to a constant header component, you will have to emit an event from each component using EventEmitter and listen to it across multiple components in your app and accordingly update the title property.

As suggested by Aamir in comments: You can have a service, wherein you can create an Observable and then update its next value in each component. The observable can then be subscribed in the header component to update the title property.

Saurabh Tiwari
  • 4,002
  • 8
  • 36
  • 69
0

You can achive this by subscribing to Router events as follows

private setTitleFromRouteData(routeData) {
    if (routeData && routeData['title']) {
        this.pageTitle = routeData['title'];
    } else {
        this.pageTitle = 'No title';
    }
}

private getLatestChild(route) {
    while (route.firstChild) {
        route = route.firstChild;
    }
    return route;
}

private subscribeToRouteChangeEvents() {
    // Set initial title
    const latestRoute = this.getLatestChild(this.activeRoute);
    if (latestRoute) {
        this.setTitleFromRouteData(latestRoute.data.getValue());
    }
    this.router.events.pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => this.activeRoute),
        map((route) => this.getLatestChild(route)),
        filter((route) => route.outlet === 'primary'),
        mergeMap((route) => route.data),
    ).subscribe((event) => {
        this.setTitleFromRouteData(event);
    });
}

I have written a complete tutorial on this matter - https://medium.com/@CROSP/page-specific-dynamic-angular-components-using-child-routes-40f3cc47ce10

CROSP
  • 4,298
  • 4
  • 36
  • 85