Error: Uncaught (in promise): TypeError: guard is not a function
Asked Answered
L

2

10

I am writing an Authguard in Angular 4 to prevent accessing routes without login. However, I am getting this error. Below is the code from Authgaurd and Routing in App module. Please help resolve the issue.

//Authgaurd Code

import { ActivatedRouteSnapshot, CanActivate, Route, Router, 
RouterStateSnapshot } from '@angular/router';
import { Store } from '';
import { Observable } from 'rxjs/Observable';
import { map, take } from 'rxjs/operators';
import { Observer } from 'rxjs';
import { Globals } from '../../app.global';
import { CRMStorageService } from '../services/storage.service';
import 'rxjs/add/operator/take';

@Injectable()
export class AuthGuard implements CanActivate {

constructor(private router: Router,private storageService: StorageService) { 
 }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
Observable<boolean> {
return this.storageService.getItem(Globals._CURRENT_USER_KEY).take(1).map 
(token => {
    if (token) {
        return true;
    } else {
        this.router.navigate(['/login']);
    }
  });
}
}

//Routes in App module

const appRoutes: Routes = [
{ path:'',redirectTo:'/login', pathMatch: 'full' },
{ path:'login', component: LoginComponent },
{ path:'reset/:token', component: ResetpasswordComponent },
{
path: '',
canActivateChild: [AuthGuard],
children: [
{ path:'dashboard', component: DashboardComponent },
{ path:'customerlist', component: CustomerlistComponent }
]
},
{ path: '**', component: ErrorComponent }
];

@NgModule({
imports: [
        RouterModule.forRoot(appRoutes,
        {
         enableTracing: false // <-- debugging purposes only
        })],
 declarations: [
  AppComponent,
 .
 .
],
providers: [AuthGuard],
exports: [],
bootstrap: [AppComponent]})

export class AppModule { }
Luing answered 25/1, 2018 at 16:33 Comment(1)
In appRoutes you are using canActivateChild, but in AuthGuard you are implementing CanActivate instead of CanActivateChildContractile
F
16

Just Replace the canActivateChild with canActivate in Your Routing handler it will work

const appRoutes: Routes = [
    { path: '', redirectTo: '/login', pathMatch: 'full' },
    { path: 'login', component: LoginComponent },
    { path: 'reset/:token', component: ResetpasswordComponent },
    {
        path: '',
        canActivate: [AuthGuard],
        children: [
            { path: 'dashboard', component: DashboardComponent },
            { path: 'customerlist', component: CustomerlistComponent }
        ]
    },
    { path: '**', component: ErrorComponent }
];

@NgModule({
    imports: [
        RouterModule.forRoot(appRoutes,
            {
                enableTracing: false // <-- debugging purposes only
            })],
    declarations: [
        AppComponent,
    .
    .
    ],
    providers: [AuthGuard],
    exports: [],
    bootstrap: [AppComponent]
})

export class AppModule { }
Fallow answered 25/1, 2018 at 21:20 Comment(1)
30 min later I find this. Amazing! Good work explaining.Orelie
M
24

You must have to implement both the CanActivate and CanActivateChild interface on the AuthGuard in order to use it on canActivateChild

export class AuthGuard implements CanActivate, CanActivateChild {
  ...
  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):  boolean {
      return this.canActivate(route, state);
 }
}
Minoan answered 29/3, 2018 at 4:21 Comment(0)
F
16

Just Replace the canActivateChild with canActivate in Your Routing handler it will work

const appRoutes: Routes = [
    { path: '', redirectTo: '/login', pathMatch: 'full' },
    { path: 'login', component: LoginComponent },
    { path: 'reset/:token', component: ResetpasswordComponent },
    {
        path: '',
        canActivate: [AuthGuard],
        children: [
            { path: 'dashboard', component: DashboardComponent },
            { path: 'customerlist', component: CustomerlistComponent }
        ]
    },
    { path: '**', component: ErrorComponent }
];

@NgModule({
    imports: [
        RouterModule.forRoot(appRoutes,
            {
                enableTracing: false // <-- debugging purposes only
            })],
    declarations: [
        AppComponent,
    .
    .
    ],
    providers: [AuthGuard],
    exports: [],
    bootstrap: [AppComponent]
})

export class AppModule { }
Fallow answered 25/1, 2018 at 21:20 Comment(1)
30 min later I find this. Amazing! Good work explaining.Orelie

© 2022 - 2024 — McMap. All rights reserved.