How to call a function on every route change in angular2
Asked Answered
K

4

40

My module.ts,

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule,Router }   from '@angular/router';
import { AppComponent }  from './crud/app.component';
import { Profile }  from './profile/profile';
import { Mainapp }  from './demo.app';
import { Navbar }  from './header/header';
// import {ToasterModule, ToasterService} from 'angular2-toaster';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({

  imports:      [ BrowserModule,FormsModule, ReactiveFormsModule ,
  RouterModule.forRoot([
      { path: '', component:AppComponent},
      { path: 'login', component:AppComponent},
      { path: 'profile', component:Profile}
    ]) ],
  declarations: [ AppComponent,Mainapp,Navbar,Profile ],
  bootstrap:    [ Mainapp ]
})
export class AppModule { 

}

Here i want to call a function from main.ts on every route change and how can i do that.Can anyone please help me.Thanks. My mainapp.ts,

    export class Mainapp {

    showBeforeLogin:any = true;
    showAfterLogin:any;
    constructor( public router: Router) {
     this.changeOfRoutes();

     }
     changeOfRoutes(){
      if(this.router.url === '/'){
         this.showAfterLogin = true;
      }
     }
}

I want to call this changeofRoutes() for every route change and how can i do that?Can anyone please help me.

Kafir answered 25/2, 2017 at 7:44 Comment(2)
it is not advisable, what your are going to do in that methodGershwin
may be this can help you https://mcmap.net/q/56431/-how-to-detect-a-route-change-in-angularHypodermic
A
75

you can call activate method from main router-outlet like this

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

which will call every time when route will change.

Update -

Another way to achieve the same is to subscribe to the router events even you can filter them out on the basis of navigation state may be start and end or so, for example -

import { Router, NavigationEnd } from '@angular/router';
  
  @Component({...})
  constructor(private router: Router) {
    this.router.events.subscribe((ev) => {
      if (ev instanceof NavigationEnd) { /* Your code goes here on every router change */}
    });
  }
Archegonium answered 25/2, 2017 at 7:55 Comment(8)
Hi pradeep,its worked greately but its not getting called when I click on back button in my browser.Kafir
i have't tested this so far, so can't say anythingArchegonium
Ok but your answer help me a lot.Thanks.Kafir
Hey Pradeep,can you answer my question?Kafir
It is working for browser back button also. I have tested this in chrome, mozilla and IE @KafirYakka
@Kafir Yes sure, what's your question!Archegonium
what if I have multiple outlets ?Sleeper
@KishanOza check my updated answer for another way to test.Archegonium
S
6

You can subscribe to the NavigationEnd event of router, and retrieve the URL with urlAfterRedirects method.

  • I strongly recommend you to use the urlAfterRedirects, because it seems that you need to showAfterLogin conditionally.

  • Let's say, you're redirecting /test-page to /; and you rely on router.url. In that case the app will already be redirected to / but router.url would return /test-page and here the issue comes ('/test-page' != '/').

Simply, make the following changes in your constructor:

export class Mainapp {
    showBeforeLogin:any = true;
    showAfterLogin:any;

    constructor(public router: Router) {
        this.changeOfRoutes();

        this.router.events
            .filter(event => (event instanceof NavigationEnd))
                .subscribe((routeData: any) => {
                    if(routeData.urlAfterRedirects === '/') {
                        this.showAfterLogin = true;
                    }
                });
    }
}
Sonatina answered 25/2, 2017 at 8:21 Comment(1)
the filter method depends on rxjs. Simply, import 'rxjs/add/operator/filter'; add this import at the beginning of your TS file, should work without a problem.Sonatina
F
5

You can call directive in Routes like below:

{ path: 'dashboard', component: DashboardComponent , canActivate: [AuthGuard] },

Your AuthGuard component is like below where you put your code:

auth.guard.ts

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, 
RouterStateSnapshot } from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {

constructor(private router: Router) { }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
{
    if (localStorage.getItem('currentUser')) {
        // logged in so return true
        return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/home'], { queryParams: { returnUrl: 
 state.url }});
    return false;
  }
 }

You should import AuthGuard component in app.module.ts file and should provide in providers:

app.module.ts:

......... Your code.......... 
import { AuthGuard } from './_guards/index';
..........Your code..............
  providers: [
    AuthGuard,
    ........
],
Freesia answered 16/3, 2018 at 5:37 Comment(0)
S
0

You can refer:NgRx Router

Catch all 'Go' actions in ngrx effects to do things just before the route changes, or in the reducer of this action to call a function after the route changes.

Stoltzfus answered 6/12, 2018 at 14:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.