← Back to list

New Angular canActivateFn Guard function

The canActivateFn is a functional route guard introduced in Angular 14. It serves the same purpose as the traditional class-based…

Meghanath Aviligonda · 2024-09-09 11:38 · 69 claps · 1.5 min read paywalled
#angular #canactivate #guards-clauses
Open on Medium ↗
Wiki topics: 🌐 · Web Development 💭 · Philosophy of Spirit

New Angular canActivateFn Guard function

The canActivateFn is a functional route guard introduced in Angular 14. It serves the same purpose as the traditional class-based CanActivate guard but allows you to define the guard logic using a simple function instead of a class. This approach can lead to more concise and readable code, especially for simple authorization checks.

auth.guard.ts

import { CanActivateFn, Router } from '@angular/router';
import { inject } from '@angular/core';
import { AuthService } from './auth.service';
export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);
  if (authService.isAuthenticated()) {
    return true;
  } else {
    router.navigate(['/login']);
    return false;
  }
};

This code is slimmer and more readable. 😊

Auth.service.ts

// auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root',
})
export class AuthService {
  private authenticated = false;
  isAuthenticated(): boolean {
    // Implement your authentication logic here
    return this.authenticated;
  }
  login(): void {
    // Perform login actions
    this.authenticated = true;
  }
  logout(): void {
    // Perform logout actions
    this.authenticated = false;
  }
}

Then, I used the Inject() function to load my Auth Service;

Then, add your new AuthGuard function to the CanActivate route array without parenthesis.

const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canActivate: [AuthGuard],
  }

auth.guard.spec.ts

import { TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';
import { authGuard } from './auth.guard';
import { AuthService } from './auth.service';
import { RouterTestingModule } from '@angular/router/testing';
describe('authGuard', () => {
  let canActivateFn: CanActivateFn;
  let authServiceSpy: jasmine.SpyObj<AuthService>;
  let routerSpy: jasmine.SpyObj<Router>;
  beforeEach(() => {
    const authSpy = jasmine.createSpyObj('AuthService', ['isAuthenticated']);
    const router = jasmine.createSpyObj('Router', ['navigate']);
    TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      providers: [
        { provide: AuthService, useValue: authSpy },
        { provide: Router, useValue: router }
      ]
    });
    canActivateFn = authGuard;
    authServiceSpy = TestBed.inject(AuthService) as jasmine.SpyObj<AuthService>;
    routerSpy = TestBed.inject(Router) as jasmine.SpyObj<Router>;
  });
  it('should allow access if user is authenticated', () => {
    authServiceSpy.isAuthenticated.and.returnValue(true);
    const result = canActivateFn(null, null);
    expect(result).toBeTrue();
    expect(authServiceSpy.isAuthenticated).toHaveBeenCalled();
    expect(routerSpy.navigate).not.toHaveBeenCalled();
  });
  it('should redirect to login if user is not authenticated', () => {
    authServiceSpy.isAuthenticated.and.returnValue(false);
    const result = canActivateFn(null, null);
    expect(result).toBeFalse();
    expect(authServiceSpy.isAuthenticated).toHaveBeenCalled();
    expect(routerSpy.navigate).toHaveBeenCalledWith(['/login']);
  });
});

Thank you!


메타데이터
post_id
bce74f7d06ea
slug
new-angular-canactivatefn-guard-function-bce74f7d06ea
url
https://medium.com/@meghanathblogger/new-angular-canactivatefn-guard-function-bce74f7d06ea
canonical_url
https://medium.com/@meghanathblogger/new-angular-canactivatefn-guard-function-bce74f7d06ea
author_url
https://medium.com/@meghanathblogger
status
ok
fetched_at
2026-07-11 16:18:17