Search code examples
angularangular-routerangular-route-guards

Angular 9 same route paths different components


I'm trying to resolve the correct path of a set of URLs that share the same structure. I have the path /:id/:areaId and /:id/:cityId and this is done by design for SEO reasons. When I come to implement it I need to know if :areaId exists (by making an API call) and if it doesn't then I will try to check if :cityId exists to navigate to it.

The first thing I thought of was the canActivate in my route because I need to inject a service and it seemed natural to me. I implemented the guard and applied to the area component and my trouble here is when the canActivate is false because the navigation stops. I've been reading about using urlMatchers however I don't think I have all information needed in the segments and injecting services using something like Angular 2 different components with same route seems wrong to me and also it does fail if I try to navigate directly to the URL as opposed to navigating via home - the injector is not defined when I do navigate directly.

My question is, using guards or something similiar, can I "navigate to the next matching URL" when the result of my guard is false?

For reference, my guard looks like this:

@Injectable()
export class AreaGuard implements CanActivate {
    constructor(private areasService: AreasService) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const areaId= route.params['areaId'];
        return this.areasService.isArea(areaId)
                                .then(a => {
                                    return true;
                                })
                                .catch(e => {
                                    console.log('Checking area', e);
                                    return false;
                                });
    }
}

Solution

  • If I were you, I would create an Component to handle this specification. Doing HTTP calls inside Guards it is something I would not recommend.

    You could have only one route and load your new created component. Do your HTTP calls and then with a simple *ngIf you could decide what component to load.