1

How to change data in one component relatively to others on route event in Angular?

For e.g. if I have three components: "nav.component", "about.component" and "service.component".

So I want to display different text in "nav.component" when I switch between about and service pages in my app.

My "app.router.ts" file:

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { ServiceComponent } from './service/service.component';

export const router: Routes = [
    { path: '', redirectTo: 'about', pathMatch: 'full' },
    { path: 'about', component: AboutComponent },
    { path: 'service', component: ServiceComponent }
];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);

I don't want to display just page name text in my nav bar while switching between these pages, it would be a custom text for each component. Also I would like to store this data/text directly in "about.component.ts" and "service.component.ts" but not in the "app.router.ts" due to maintainability and scalability.

Is it possible?

U.P.D.

This is my "app.component.html" file:

<div class="container">

  <!-- Nav Bar (text changes here) -->
  <app-nav></app-nav>

  <!-- Pages (components which are included in app.router.ts) -->
  <router-outlet></router-outlet>

</div>

For e.g. this is "about.component.ts" file:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {
  const text_for_nav_bar = "This is my new About page."; // <-- text that should be displayed in nav component for this page on router event.

  constructor() { }

  ngOnInit() {
  }

}
NOtherDev
  • 9,542
  • 2
  • 36
  • 47
mr.boris
  • 3,667
  • 8
  • 37
  • 70
  • Your requirement is not clear. What is nav.component? How is your application structured? What do you mean by custom text? Where do you want to display it? All this information is required to answer your question. – Vinod Bhavnani Dec 12 '17 at 09:50
  • u can do that with route change events: https://stackoverflow.com/questions/33520043/how-to-detect-a-route-change-in-angular-2 – Dhyey Dec 12 '17 at 09:57
  • @VinodBhavnani, I've updated my post, hope this will help. I want to store custom text string for each component and this string should be displayed in `nav` component depending on router. – mr.boris Dec 12 '17 at 10:26

3 Answers3

1

One way would be with *ngIf (or [hidden] if you want to load all contents to the DOM at once). And to catch current route, inject Router module:

class NavComponent {
    constructor(private router: Router){

    }
}

and in nav.component.html:

<div *ngIf="router.url === '/some/route'">
 text for this route
</div>
<div *ngIf="router.url === '/other/route'">
 text for other route
</div>

Doing same in component.ts, could be:

nav.component.html:

<h1>{{yourText}}</h1>

component.ts:

ngOnInit() {
  if(this.router.url == '/some/route') {
    yourText = 'Text'
  } elseif(this.router.url == '/other/route') {
    yourText = 'Other text'
  }
}
Julius Dzidzevičius
  • 10,775
  • 11
  • 36
  • 81
  • now I think that might be needed to trigger Change Detection and use other cycle hook. If it doesnt work, plese let me know. Its been a while I've done something with Angular – Julius Dzidzevičius Dec 12 '17 at 10:35
  • I've just checked out your example above, unfortunately it doesn't work. `this.router.url` doesn't return a path, just one slash only. – mr.boris Dec 12 '17 at 11:25
  • So its probably returns the root path. But it never changes while navigating, because navComponent was initialised only once. Subscribing to Router events is the right way, as @Shabbir Dhangot wrote, just I am not guarantied about his logic (I forgot Angular a bit) – Julius Dzidzevičius Dec 12 '17 at 12:31
  • 1
    All in all, `*ngIf` with `router.url` works well, but slightly improper for this case. – mr.boris Dec 12 '17 at 15:04
1

Using below code you will able to subscribe router change events. You need to add this code on nav bar.

Import router and Navigation start

import { Router, ActivatedRoute, NavigationStart } from '@angular/router';
import "rxjs/add/operator/filter";
import "rxjs/add/operator/pairwise";

Add below code in constrictor.

this.router.events
  .filter(event => event instanceof NavigationStart)
  .pairwise()
  .subscribe((value: [NavigationStart, NavigationStart]) => {
     let nextUrl = value[1].url;
     if (nextUrl == '/about') {
         // your code here for next url
     }
  },
    (err) => {

    },
    () => { });
}

});
Shabbir Dhangot
  • 8,954
  • 10
  • 58
  • 80
0

You should use router datas

export const router: Routes = [
    { path: '', redirectTo: 'about', pathMatch: 'full' },
    { path: 'about', component: AboutComponent, data: {navigationText: 'Some text'} },
    { path: 'service', component: ServiceComponent, data: {navigationText: 'Some other text'} }
];

and in app.component.html

<div class="container">

    <app-nav text="outlet.activatedRouteData.navigationText"></app-nav>

    <router-outlet #outlet="outlet"></router-outlet>

</div>

Of course you need to add a "@Input text: string" property in nav.component.ts

Vincent Verrier
  • 221
  • 3
  • 5