Issue
My Angular app includes a simple AuthGuard
as shown below and there has never been a problem with it. Recently, I upgraded my Angular version from 15.1.4 to 15.2.0 and since then, my IDE indicates that both CanActivate
and CanActivateChild
are deprecated.
The official Angular documentation for CanActivate
says:
Deprecated: Use plain JavaScript functions instead.
How would I need to adjust the code below to get rid of the deprecated warning?
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthenticationService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.authService.checkLogin()
.pipe(
map(() => true),
catchError(() => {
this.router.navigate(['route-to-fallback-page']);
return of(false);
}
)
);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.canActivate(route, state);
}
}
Solution
The trick is to rely on inject()
for the injection of the instances you need :
export const canActivate: CanActivateFn = (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) => {
const authService = inject(AuthenticationService);
const router = inject(Router);
return authService.checkLogin().pipe(
map(() => true),
catchError(() => {
return router.createUrlTree(['route-to-fallback-page']);
})
);
};
export const canActivateChild: CanActivateChildFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => canActivate(route, state);
inject()
allows you to use the dependency injection when you are in an injection context. For example in a constructor or like here when passing a function to a core Angular feature.
You can also read about it on the depreciation list.
Also Since v16, Angular provides some helper functions to convert classes to functionnal guards like mapToCanActivate
:
@Injectable({providedIn: 'root'})
export class AdminGuard {
canActivate() {
return true;
}
}
const route: Route = {
path: 'admin',
canActivate: mapToCanActivate([AdminGuard]),
};
You can find the others here.
Answered By - Matthieu Riegler
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.