Question presented to candidate:
"Our codebase has thirty @Injectable guard classes implementing CanActivate. A new teammate writes guards as plain functions. Explain the difference, whether the classes are deprecated in Angular 22, and how you would migrate."
What a strong answer should cover:
- A class-based guard is an
@Injectableclass implementing an interface such asCanActivate; the route lists the class as a DI token. - A functional guard is a
CanActivateFn(orCanMatchFn,CanDeactivateFn...) that gets dependencies withinject(), because the router calls it inside an injection context. - In the 22.2.3 typings, passing a class or token in the route array is deprecated (
DeprecatedGuard), while theCanActivateinterface itself is not marked deprecated;mapToCanActivate([MyGuard])wraps a class as a function. - Functions are smaller, composable (guard factories like
hasRole("admin")), and need no provider registration. inject()must be called synchronously, before anyawait; afterwards it throwsNG0203.- Async guards in one array start together, and the result is decided in array order.
Clarifying questions expected:
- "Are the class guards shared with other code, or only referenced from routes?"
- "Do the guards have unit tests we need to keep passing during the migration?"
Code / implementation expected: Yes β the same rule written as a class, as a mapped class, as a function, and as a guard factory.