Angular 2 Router Guards order

what will be the order of execution for both the guards.

They will be run synchronously without waiting for each other.

if i want to execute AuthGuard only if CanAlwaysActivateGuard returns true, would that be possible.

No, it's not possible with current implementation. As a workaround you can create a wrapper guards to run your guards in order.

Also see this How to wait for guards in Angular.


I had this problem and came across your post in my search for answers. Finding none -- and having some time today -- I came up with a solution I thought you might be interested in. I created a "CompositeRouteGuard":

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

@Injectable()
export class CompositeRouteGuard implements CanActivate {

  constructor(  protected router: Router,
                protected injector: Injector ) {
  }

  canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> {
    var compositeCanActivateObservable: Observable<boolean> = Observable.of(true);

    let routeGuards = route.data.routeGuards;

    if(routeGuards){
      for( var i = 0; i < routeGuards.length; i++ ){
        let routeGuard = this.injector.get(routeGuards[i]);
        let canActivateObservable = routeGuard.canActivate(route, state);
        compositeCanActivateObservable = compositeCanActivateObservable.flatMap( (bool) => {
          if(!bool){
            return Observable.of(false);
          }
          else{
            return canActivateObservable;
          }
        });
      }
    }

    return compositeCanActivateObservable;
  }
}

That requires a little extra configuration in your routes.ts. You need to add a "routeGuards" array to the data element of the route.

const routes: Routes = [
  {
    path: '...',
    component: AComponent,
    data: { routeGuards: [ FooRouteGuard, BarRouteGuard, BazRouteGuard ] },
    canActivate: [ CompositeRouteGuard ]
  },
...

I only cared about the canActivate action, but you should be able to easily extend this, to say "canDeactivate" (for example) if you need to.

Now my route guards run "in order" with "and" semantics (all must succeed for route to be activated).


If you nest them, you can decide their order:

import { Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    canActivate: [CanAlwaysActivateGuard],
    children: [
      {
        path: '',
        canActivate: [AuthGuard],
        children: [
          // (...)
        ],
      }
    ],
  }
];

An outer route guard is evaluated before any inner route guards.