14

I want to change a certain heading according to the current url in Angular. So component.ts looks like this:

import {Router} from '@angular/router';
//code
public name: string
constructor(
    public router: Router
  ) {}
getName()
{
if(this.router.url === "/some_list")
{this.name = "List"}
else if(this.router.url === "/detail")
{this.name = "Detail"}
}

And then

<a>{{this.name}}</a>

The existing answers, like How to detect a route change in Angular? could not tell me how to do something after a change in routing (change = true or false). So how can I run this function whenever the url changes, so that the heading is according to the current view?

5 Answers5

15

You can subscribe to router event in the app.component.ts. It will fire every time you change the route.

  constructor(location: Location, router: Router) {
    // decide what to do when this event is triggered.
    router.events.subscribe(val => {
      if (location.path() != "/something") {
          // do something
      } else {
         // do something else
      }
    });
  }

Try this if it is calling multiple times

router.events.filter(event => event instanceof NavigationEnd).subscribe(val => { // here your code... })

Note: I have not tried this


Surjeet Bhadauriya
  • 6,755
  • 3
  • 34
  • 52
7

Go this StackBlitz link

On every navigation start event of router you can get url and fire function. in you app.component.ts

ngOnInit(){
   this.router.events.subscribe(event =>{
      if (event instanceof NavigationStart){
         console.log(event.url)
         this.routerChangeMethod(event.url);
      }
   })
}

routerChangeMethod(url){
  this.title = url;
}

Yout app.component.html is..

{{title}}

<router-outlet></router-outlet>
Developer
  • 3,309
  • 2
  • 19
  • 23
2

As a good practice you should have one component per route.

RouterModule.forRoot([
    { path: 'products', component: DetailComponent },
    { path: 'shopping-cart', component: SomelistComponent }
])

If you keep to this practice, then you will have a separation of concern.

And then according to the route you just set header for your component.

You can read more about routing here.

StepUp
  • 36,391
  • 15
  • 88
  • 148
  • 1
    I totally agree - I have already one component per rule, but I have an extra component for the contenttab to navigate between these components - and for a special use cas of this contenttabs I need the headings –  Dec 16 '19 at 11:32
2

Try like this:

Working Demo

.html

<a routerLinkActive="active" routerLink="/some_list">Home</a> |
<a routerLinkActive="active" routerLink="/detail">Catalog</a>

<router-outlet (activate)="getName()"></router-outlet>

.ts

getName() {
  if (this.router.url.includes("some_list")) {
      this.name = "some_list";
  } else if (this.router.url.includes("detail")) {
      this.name = "detail";
  }
  alert(this.name);
}
Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
  • I think I read that its bad practice to use methods in the markup. These methods will be called a lot of times during the render phases. Check answer from GaurangDhorda below instead – Jens Alenius Oct 28 '20 at 11:57
0

After observing some issues in the comment I thought I should post this as an alternative solution if it helps someone. We will cater 2 issues in this solution:

  1. Handling contents based on the route.
  2. Avoiding multiple checking of the same function

For that, instead of using OnInit it is better to handle it in the constructor as it is better and will be checked earlier.

constructor(private router: Router) {
  this.router.events.subscribe((event: any) => {
    if (event instanceof NavigationEnd) {
      // handle NavigationEnd event here
      console.log(event.url);
    }
  });
}
Ahmad Habib
  • 2,053
  • 1
  • 13
  • 28