Search code examples
angularangular2-routing

Angular 2 - Route guard not working on browser refresh


Having these routes defined in app.module.ts

...
{ path: 'mypath', component: MyComponent, canActivate: [RouteGuard] }, 
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/home'}

and this guard service

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AngularFire } from 'angularfire2';
import { AngularFireAuth } from 'angularfire2';

@Injectable()

export class RouteGuard implements CanActivate {

  private loggedIn: boolean;

  constructor ( private af: AngularFire, private auth: AngularFireAuth ) {}

  canActivate(): boolean {

    this.auth.subscribe(auth => {
      if  (auth)  { this.loggedIn = true; }
      else        { this.loggedIn = false; }
//          this.router.navigate(['/login']); for future implememtation
       });

    return this.loggedIn;
  }
}

refreshing the browser from url //mysite/mypath the app goes to //mysite instead of //mysite/mypath (and also skips the default route).

Without any guard activated on mypath route (ie: { path: 'mypath', component: MyComponent }everything works perfectly.

Does anybody knows if this is an Angular bug ? How could I avoid this behaviour ?

My dev env is:

@angular/cli: 1.0.0-rc.1
node: 7.5.0
os: linux x64
@angular/cli: 1.0.0-rc.1
@angular/common: 2.4.9
@angular/compiler: 2.4.9
@angular/compiler-cli: 2.4.9
@angular/core: 2.4.9
@angular/flex-layout: 2.0.0-rc.1
@angular/forms: 2.4.9
@angular/http: 2.4.9
@angular/material: 2.0.0-beta.2
@angular/platform-browser: 2.4.9
@angular/platform-browser-dynamic: 2.4.9
@angular/router: 3.4.9

Thanks for helping me.

PS: I have tried to find an answer both on Stack Overflow or on Github issues without finding an answer. I saw a similar question Angular 2 routing not working on page refresh with Apache, but this is not my case.


Solution

  • you can an asynchronous result to the route guard :

     canActivate(): Promise<boolean> {
       let self = this;
        return this.auth.toPromise().then(auth => {
             if  (auth)  { self.loggedIn = true; }
             else { self.loggedIn = false; }
    
             self.router.navigate(['/login']); for future implememtation
    
            return self.loggedIn;
        });
    
    
    }