Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular(5) - lazy loading and canActivate guard - StaticInjectorError

So, we have quite a big app and we started working on optimizations.... one of the optimizations were lazy loading some parts....

so we have Demo pages with whole load of example usage that we DON'T want anywhere but on out DEV environment...

so lazy loading that part was quite easy...

in our app-routing module we have

const routes: Routes = [
    ...
    {path: 'design', canActivate: ['DevOnlyGuard'], loadChildren: 'app/pages/demo/demo.module#DemoPagesModule'},
    ...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

So without canActivate route all works fine and demo routes are loaded lazily...

now, if I add this canActivate in my guard, that looks like this

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

@Injectable()
export class DevOnlyGuard implements  CanActivate, CanActivateChild {
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    return (environment.envName === 'dev');
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    return this.canActivate(route, state);
  }
}

I am getting this error once I hit the demo route:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError[DevOnlyGuard]:
StaticInjectorError[DevOnlyGuard]: NullInjectorError: No provider for DevOnlyGuard! Error: StaticInjectorError[DevOnlyGuard]: ....

even if I added the Guard to the list of providers in my app.module like

providers: [
    ...
    DevOnlyGuard,
];

Any ideas?

like image 902
DS_web_developer Avatar asked Dec 07 '17 17:12

DS_web_developer


1 Answers

remove single quotes from canActivate: ['DevOnlyGuard']

Below is how should we use canActivate:

Method 1:

  @Injectable()
    class CanActivateTeam implements CanActivate {
      constructor(private permissions: Permissions, private currentUser: UserToken) {}

      canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<boolean>|Promise<boolean>|boolean {
        return this.permissions.canActivate(this.currentUser, route.params.id);
      }
    }

    @NgModule({
      imports: [
        RouterModule.forRoot([
          {
            path: 'team/:id',
            component: TeamCmp,
            canActivate: [CanActivateTeam]
          }
        ])
      ],
      providers: [CanActivateTeam, UserToken, Permissions]
    })
    class AppModule {}

Method 2(with Single Quote...):

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        canActivate: ['canActivateTeam']
      }
    ])
  ],
  providers: [
    {
      provide: 'canActivateTeam',
      useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => true
    }
  ]
})
class AppModule {}
like image 171
Haifeng Zhang Avatar answered Sep 19 '22 17:09

Haifeng Zhang