Service en ligne 100% Gratuit Utilitaires Web AngularForAll

- Générateur de Guard & Resolver Angular

Générateur Guard Angular Canactivate Guard Angular Typescript Candeactivate Canmatch Guard Angular Resolver Angular Fonctionnel Angular Router Protection Authentification

Générez le code TypeScript de vos Guards Angular (CanActivate, CanDeactivate, CanMatch) et Resolvers. Style functional ou class-based, prêt à copier-coller.

🛡️

Générateur de Guard & Resolver Angular

🔧 Configuration

camelCase pour functional, PascalCase pour class
💡 Astuce : Le code se régénère automatiquement à chaque modification.

Guards et Resolvers Angular — Guide complet

Dans Angular, les Guards et Resolvers sont des intercepteurs du cycle de navigation du Router. Ils permettent de contrôler qui peut accéder à quoi, quand et avec quelles données — sans polluer vos composants avec de la logique de navigation. Ce guide couvre les cinq types disponibles, la différence entre les functional guards (Angular 15+) et les class-based guards, ainsi que les bonnes pratiques d'organisation dans vos projets.

CanActivate — Protéger l'accès à une route

CanActivate est le guard le plus courant. Il s'exécute avant l'activation d'un composant et permet de bloquer la navigation si une condition n'est pas remplie — par exemple, l'utilisateur n'est pas authentifié.

// Functional guard (Angular 15+) — auth.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router      = inject(Router);

  if (authService.isAuthenticated()) {
    return true;
  }

  // Redirige vers /login avec l'URL d'origine en query param
  return router.createUrlTree(['/login'], {
    queryParams: { returnUrl: state.url }
  });
};

Le guard peut retourner un boolean, une UrlTree (redirection) ou un Observable<boolean | UrlTree>. En retournant une UrlTree plutôt que false, Angular gère la redirection de façon atomique et évite les conditions de course.

CanActivateChild — Protéger les routes enfants

CanActivateChild fonctionne comme CanActivate mais s'applique à chaque route enfant d'un groupe. Il est idéal pour protéger une section complète (ex: tous les sous-routes d'un espace admin) sans dupliquer le guard sur chaque route.

// app.routes.ts — Protéger toutes les routes enfants de /admin
{
  path: 'admin',
  canActivateChild: [authGuard],
  children: [
    { path: 'users', component: UsersComponent },
    { path: 'settings', component: SettingsComponent },
    { path: 'logs', component: LogsComponent },
  ]
}

CanDeactivate — Bloquer la sortie d'une route

CanDeactivate s'exécute avant que l'utilisateur quitte une route. C'est l'outil parfait pour avertir d'un formulaire non sauvegardé ou d'une action en cours. Le guard a accès à l'instance du composant actif via son type générique.

// unsaved-changes.guard.ts
import { CanDeactivateFn } from '@angular/router';
import { EditFormComponent } from './edit-form.component';

export const unsavedChangesGuard: CanDeactivateFn<EditFormComponent> = (component) => {
  if (component.hasUnsavedChanges()) {
    return confirm('Modifications non sauvegardées. Quitter quand même ?');
  }
  return true;
};
Bonne pratique : Plutôt qu'un confirm() natif, utilisez une modale Angular Material ou Bootstrap pour une meilleure expérience utilisateur. Le guard peut retourner un Observable<boolean> émis par la modale.

CanMatch — Contrôler le matching de route

CanMatch (introduit en Angular 14.1, remplaçant de CanLoad) détermine si une route doit être matchée avant même d'être chargée. C'est plus puissant que CanActivate car il empêche le lazy loading du bundle si la condition n'est pas remplie — parfait pour les feature flags ou les rôles utilisateurs.

// feature.guard.ts
import { inject } from '@angular/core';
import { CanMatchFn, Router } from '@angular/router';
import { FeatureFlagService } from './feature-flag.service';

export const betaFeatureGuard: CanMatchFn = (route, segments) => {
  const featureService = inject(FeatureFlagService);
  const router         = inject(Router);

  return featureService.isEnabled('betaFeature')
    ? true
    : router.createUrlTree(['/not-found']);
};

Contrairement à CanActivate, si CanMatch retourne false, Angular continue d'essayer les autres routes correspondantes dans la configuration. Cela permet des configurations multi-routes élégantes selon le contexte.

Resolve — Pré-charger les données avant l'activation

Un Resolver pré-charge des données avant que le composant ne soit instancié. Le composant reçoit les données via ActivatedRoute.data, sans état de chargement à gérer dans le template.

// user.resolver.ts
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { User } from './user.model';
import { UserService } from './user.service';

export const userResolver: ResolveFn<User> = (route) => {
  return inject(UserService).getById(route.paramMap.get('id')!);
};

// app.routes.ts
{
  path: 'users/:id',
  component: UserDetailComponent,
  resolve: { user: userResolver }
}

// user-detail.component.ts
export class UserDetailComponent {
  user = inject(ActivatedRoute).snapshot.data['user'] as User;
}

Functional Guards vs Class-based — que choisir ?

Critère Functional (Angular 15+) Class-based
Syntaxe Fonction avec inject() @Injectable + implements
Boilerplate ✅ Minimal ❌ Verbeux
Composition ✅ Composable (and(), or()) Limitée
Tests ✅ Plus simples (pas de TestBed requis) Nécessite TestBed
Compatibilité Angular 15+ Angular 2+
Recommandation 🎯 Nouveaux projets Angular 15+ Projets legacy

Composition de Guards avec and() et or()

Angular 15.2+ offre les helpers and() et or() dans le package @angular/router pour composer plusieurs guards de façon déclarative, sans logique conditionnelle manuelle.

import { and, or } from '@angular/router';
import { authGuard } from './auth.guard';
import { roleGuard } from './role.guard';
import { featureGuard } from './feature.guard';

// Doit être authentifié ET avoir le rôle admin
const adminGuard = and([authGuard, roleGuard('admin')]);

// Peut être admin OU superuser
const staffGuard = or([roleGuard('admin'), roleGuard('superuser')]);

Organisation et bonnes pratiques

Structure recommandée des guards :
  • src/app/core/guards/auth.guard.ts — Guard d'authentification
  • src/app/core/guards/role.guard.ts — Guard de rôles
  • src/app/core/guards/unsaved-changes.guard.ts — CanDeactivate formulaire
  • src/app/core/resolvers/user.resolver.ts — Resolver utilisateur
  • src/app/features/admin/guards/admin.guard.ts — Guard feature-specific

Gardez les guards simples et à responsabilité unique. Un guard qui fait trop de choses devient difficile à tester. Utilisez l'injection de dépendances pour déléguer la logique aux services (AuthService, PermissionService, FeatureFlagService).

FAQ — Guards et Resolvers Angular

CanActivate s'exécute après que la route est matchée (et donc le bundle potentiellement téléchargé). CanMatch s'exécute avant : si la condition échoue, Angular essaie la route suivante dans la configuration et ne charge pas le bundle lazy. Utilisez CanMatch pour les modules lazy-loaded conditionnels (feature flags, rôles) et CanActivate pour la protection après chargement.

Les functional guards sont des fonctions pures, testables sans TestBed si les services injectés sont mockés correctement. Vous pouvez utiliser runInInjectionContext du package @angular/core/testing pour fournir un contexte d'injection minimal.
import { runInInjectionContext } from '@angular/core';
it('should redirect unauthenticated users', () => {
  const result = runInInjectionContext(injector, () =>
    authGuard(mockRoute, mockState)
  );
  expect(result).toBeInstanceOf(UrlTree);
});

Oui. Un guard peut retourner un Observable<boolean | UrlTree>. Angular attend que l'Observable se complète avant de poursuivre la navigation. Cela permet de faire des appels API asynchrones (ex: vérifier une session côté serveur). Pensez à utiliser take(1) ou first() pour s'assurer que l'Observable se complète.

CanLoad est déprécié depuis Angular 15.1. Son remplaçant direct est CanMatch, qui offre les mêmes fonctionnalités (empêcher le chargement des modules lazy) tout en étant plus flexible : il permet plusieurs routes avec le même path et différents guards selon le contexte.

Le resolver reçoit l'objet ActivatedRouteSnapshot en premier argument. Vous pouvez lire les paramètres de route (route.paramMap.get('id')), les query params (route.queryParamMap) ou les données statiques (route.data) pour adapter le comportement du resolver selon la route active.

Conclusion

Les Guards et Resolvers Angular sont des outils essentiels pour construire des applications robustes et sécurisées. Avec l'introduction des functional guards en Angular 15, le code est devenu significativement plus concis et testable. Utilisez CanActivate pour l'authentification, CanDeactivate pour protéger les formulaires, CanMatch pour les feature flags avec lazy loading, et les Resolvers pour éliminer les états de chargement dans vos composants.

Ce générateur vous fournit une base de code propre et prête à l'emploi. Adaptez les noms, les services et les logiques métier selon votre architecture, et consultez la documentation officielle Angular Router pour aller plus loin.

Partager