Reputation: 682
I'm having a route /invoices/:invoiceId
for an invoice detail view which needs to be protected with 2 conditions
My idea was to use a guard for authentication state - and since the view needs the invoice data - a resolver for loading the invoice.
But, what if the data can't be loaded from the resolver? E.g. server error, authenticated user not allowed to load the given invoice id, ... What's the best approach here?
null
and handle the redirect from the component?InvoiceComponent
?Since guards are executed before any resolvers, i can't add another guard at the end.
Route
{
path: 'invoice/:invoiceId',
component: InvoiceComponent,
canActivate: [authGuard],
resolve: { invoice: invoiceResolver }
}
auth.guard.ts
export const authGuard: CanActivateFn = (_route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
const authenticationPolicy = inject(AuthenticationPolicy);
const router: Router = inject(Router);
return authenticationPolicy.isGranted().pipe(
catchError(() => {
const queryParams = { referrer: state.url };
const redirectUrl: UrlTree = router.createUrlTree(['login'], { queryParams });
return of(redirectUrl);
})
);
};
invoice.resolver.ts
export const invoiceResolver: ResolveFn<Observable<Invoice | null>> = (route: ActivatedRouteSnapshot) => {
const invoiceId = parseInt(route.paramMap.get('invoiceId') ?? '0', 10);
const invoiceApiService = inject(InvoiceApiService);
return invoiceApiService.invoice(invoiceId).pipe(catchError(() => of(null)));
};
Upvotes: 1
Views: 97