I'm working on an application where most URLs starts with a couple of dynamic parameters. Something like this:
https://projects/:projectId/:subProjectId/<service>/..
However, currently there is no validation of these IDs and I am looking for a proper way to intercept, validate and re-route (if not valid) on every navigation change. Basically I want to parse the URL (using route.paramMap
or similar), query the backend DB to check if the IDs exists and re-route to a "Not Found" page if they do not.
I know there are several ways to check for a route change, but I am not sure what the proper approach is for this case. I could subscribe to a routing event or do something like:
<router-outlet (activate)="changeOfRoute()"></router-outlet>
This does not feel correct however as I am not really intercepting the route change and validating/redirecting before the navigation starts. I could also use a route resolver:
resolve: { resolver: IdValidationResolverService}
This is not very practical as I would need to ensure the resolver is used on every route and it's children instead of having something global that applies to every navigation change.
I could use some input on the correct way of handling this.
CodePudding user response:
I think what you need is Guard
, for example:
@Injectable({
providedIn: 'root'
})
export class IdValidatorGuard implements CanActivate {
constructor(private http: HttpClient, private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean |
UrlTree {
const id = next.paramMap.get('id');
return this.http.get(`api/validateId/${id}`).pipe(
map(result => {
if (result) {
return true;
} else {
this.router.navigate(['/404']);
return false;
}
})
);
}
}