C'est quoi un Guard ?
Un Guard permet dâautoriser ou non la navigation vers une route. Il existe plusieurs types de Guard dans Angular.
CanActivate
Un cas courant est une route quâon ne peut accĂ©der que si on est connectĂ© Ă lâapplication.
export function isLoggedInGuard(): CanActivateFn {
return (route, state) => {
const router = inject(Router);
const isAuthenticated = inject(AuthService).isAuthenticated;
if (isAuthenticated()) return true;
return this.router.parseUrl("/login");
};
}
Ici on a dĂ©finit un Guard qui vĂ©rifie si le user est connectĂ©, si câest le cas on renvoie true donc on peut accĂ©der Ă la route, sinon on retourne la route login ce qui annule la navigation prĂ©cĂ©dente et navigue vers la route login.
Il ne nous reste plus quâĂ utiliser ce Guard dans une Route.
export const routes: Route[] = [
{
path: "profile",
component: ProfileComponent,
canActivate: [isLoggedInGuard],
},
];
CanDeactivate
canDeactivate est lâinverse de canActivate. Il permet de vĂ©rifier si on peut quitter une route. Par exemple, si on a un formulaire non sauvegardĂ©, on pourrait vouloir afficher un message de confirmation avant de quitter la route.
export const canDeactivateFeedbackRouteGuard: CanDeactivateFn<FeedbackRoute> = (
component: FeedbackRoute
) => {
if (!component.formCompleted()) {
return window.confirm("Are you sure you want to leave?");
} else {
return true;
}
};
Ici, on vĂ©rifie si le formulaire est complĂ©tĂ©, si ce nâest pas le cas on demande une confirmation avant de quitter la route.
On utilise ce Guard de la mĂȘme maniĂšre que canActivate en le plaçant dans la route.
CanMatch
canMatch permet de vĂ©rifier si une route peut ĂȘtre activĂ©e, tout comme canActivate, mais si ce nâest pas le cas alors le router va essayer de matcher une autre route avec le mĂȘme path.
export function hasRoleGuard(role: Role): CanActivateFn {
return (route, state) => {
const role$ = inject(UserStore).role$:
// actuellement ce role đ est 'student'
return role$.pipe(map(userRole => userRole === role));
};
}
export const appRoutes: Route[] = [
{
path: "room",
loadComponent: () => import("./teachers-room.component"),
// grĂące Ă canMatch, le router va sauter ce path et essayer
// le path 'room' suivant car đ renvoie false
canMatch: [hasRoleGuard("teacher")],
},
{
path: "room",
loadComponent: () => import("./students-room.component"),
// et ici, đ renvoie true donc đ va ĂȘtre chargĂ©
canMatch: [hasRoleGuard("student")],
},
];