0

I have routes config

const appRoutes: Routes = [
  { path: '', loadChildren: 'app/+home/home.module#HomeModule' },
  { path: 'auth', loadChildren: 'app/+auth/auth.module#AuthModule' },
  { path: ':category', loadChildren: 'app/+search/search.module#SearchModule' },
  {
    path: '**',
    component: PageNotFoundComponent,
    data: { title: 'Page not found' }
  },
];

I need to check if :category route param value exist as a search category in database, if so activate route, else go to 404 page (in this case PageNotFoundComponent).

Using CanActivate is the best way? How about navigating to 404 page?

Rakhat
  • 4,783
  • 4
  • 40
  • 50

1 Answers1

1

Yes, you could use the CanActivate guard.

{
  path: ':category',
  loadChildren: 'app/+search/search.module#SearchModule'
  canActivate: [CanActivateCategory]
},

Then, do the redirect inside the guard:

@Injectable()
class CanActivateCategory implements CanActivate {

  constructor(private router: Router,
              private categoryService: CategoryService) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    const obs = this.categoryService.categoryExists(route.params['category']);
    obs.subscribe((exists: boolean) => {
      if (!exists) this.router.navigate('/404');
    });
    return obs;
  }
}

This code assumes that you have a CategoryService to verify the existence of the category, and that you have declared a route for the path /404.

Final note: if you need to pre-load some data for the current :category, I'd put this code in a Resolve. That way, you can do it all in one place: pre-load the data, or if the data couldn't be found/preloaded, redirect to /404.

AngularChef
  • 13,797
  • 8
  • 53
  • 69
  • So I need to change 404 route path from `**` to `404`? – Rakhat Jan 23 '17 at 11:55
  • 1
    Ah, I missed the `**` route in your code. Well, if you want to be able to explicitly redirect users to a "not found" page, then yes it's better to have a specific path for it like `404`. You can keep the `**` route with a `redirectTo: '404'`. – AngularChef Jan 23 '17 at 11:58